合并C#中的两个列表,并将具有相同id的对象合并到一个列表项中

Iai*_*ser 6 .net c# linq list

我已经想到了,我如何才能在我自己的滚动解决方案来解决这个问题,但我想,如果.NET已经具备了什么,我想acheive功能 - 如果是这样,我宁愿使用一些内置.

假设我有一个的两个实例Widget对象,让我们称他们PartA和PartB.来自每个的信息来自两个不同的Web服务,但两者都具有匹配的ID.

PartA
{
    ID: 19,
    name: "Percy",
    taste: "",
    colour: "Blue",
    shape: "",
    same_same: "but different"
}

PartB
{
    ID: 19,
    name: "",
    taste: "Sweet",
    colour: "",
    shape: "Hexagon",
    same_same: "but not the same"
}
Run Code Online (Sandbox Code Playgroud)

我想合并这些来创建以下内容:

Result
{
    ID: 19,
    name: "Percy",
    taste: "Sweet",
    colour: "Blue",
    shape: "Hexagon",
    same_same: "but different"
}
Run Code Online (Sandbox Code Playgroud)

注意same_same每个值之间的值是如何不同的,但我们认为PartA是主节点,因此结果保留了值but different.

现在让问题复杂化:

假设我们有两个列表:

List<Widget> PartA = getPartA();
List<Widget> PartB = getPartB();
Run Code Online (Sandbox Code Playgroud)

现在这里有一些描述我想做的伪代码:

List<Widget> Result = PartA.MergeWith(PartB).MergeObjectsOn(Widget.ID).toList();
Run Code Online (Sandbox Code Playgroud)

Tim*_* S. 13

您可以编写自己的扩展方法,如下所示:

static class Extensions
{
    public static IEnumerable<T> MergeWith<T>(this IEnumerable<T> source, IEnumerable<T> other) where T : ICanMerge
    {
        var otherItems = other.ToDictionary(x => x.Key);
        foreach (var item in source)
        {
            yield return (T)item.MergeWith(otherItems[item.Key]);
        }
    }
    public static string AsNullIfEmpty(this string s)
    {
        if (string.IsNullOrEmpty(s))
            return null;
        else
            return s;
    }
}
Run Code Online (Sandbox Code Playgroud)

在哪里ICanMerge:

public interface ICanMerge
{
    object Key { get; }
    ICanMerge MergeWith(ICanMerge other);
}
Run Code Online (Sandbox Code Playgroud)

实施例如:

public class Widget : ICanMerge
{
    object ICanMerge.Key { get { return this.ID; } }
    int ID {get;set;}
    string taste {get;set;}
    public ICanMerge MergeWith(ICanMerge other)
    {
        var merged = new Widget();
        var otherWidget = (Widget)other;
        merged.taste = this.taste.AsNullIfEmpty() ?? otherWidget.taste;
        //...
        return merged;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后就这么简单PartA.MergeWith(PartB).ToList().