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

我已经考虑过如何通过推出自己的解决方案来解决这个问题,但我想知道.NET是否已经具备了我想要实现的功能 – 如果是这样的话,我宁愿使用内置的东西.

假设我有一个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"
}

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

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

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

现在让问题复杂化:

假设我们有两个列表:

List<Widget> PartA = getPartA();
List<Widget> PartB = getPartB();

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

List<Widget> Result = PartA.MergeWith(PartB).MergeObjectsOn(Widget.ID).toList();
最佳答案
您可以编写自己的扩展方法,如下所示:

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;
    }
}

ICanMerge就像:

public interface ICanMerge
{
    object Key { get; }
    ICanMerge MergeWith(ICanMerge other);
}

已实施,例如喜欢:

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;
    }
}

然后它就像PartA.MergeWith(PartB).ToList()一样简单.

转载注明原文:合并C#中的两个列表,并将具有相同id的对象合并到一个列表项中 - 代码日志