合并2个集合,更喜欢第二个集合的项目

时间:2012-03-28 08:52:40

标签: c# linq

我有2个对象集合。对象有一个对象类型'key'属性(我使用object.ReferenceEquals来测试键)。如何合并集合A和B以生成具有A和B的所有项目但不具有与B中的项目具有匹配键的A的那些项目的不同集合C?

编辑:请注意,收藏品也可能是空的。

4 个答案:

答案 0 :(得分:2)

这应该有效:

var toMergeA = A.Where(x => !B.ContainsKey(x.Key));
var C = toMergeA.Union(B);

答案 1 :(得分:1)

这也是一种可能的解决方案:

var C = B.Concat(A.Where(a => !B.Any(b => a.Key == b.Key)));

答案 2 :(得分:0)

这样可行,但它返回一个匿名项列表。

public class X
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Y
{
    public int Id { get; set; }
    public int Age { get; set; }
}

List<X> xList = new List<X>();
xList.Add(new X() { Id = 0, Name = "a" });
xList.Add(new X() { Id = 1, Name = "b" });
xList.Add(new X() { Id = 2, Name = "c" });
xList.Add(new X() { Id = 3, Name = "d" });

List<Y> yList = new List<Y>();
yList.Add(new Y() { Id = 0, Age=20 });
yList.Add(new Y() { Id = 2, Age = 30 });
yList.Add(new Y() { Id = 4, Age = 40 });


var xQuery = from x in xList
             select new
             {
                 Id = x.Id                             
             };
var yQuery = from y in yList
             select new
             {
                  Id = y.Id

              };


        var un = xQuery.Except(yQuery).Union(yQuery);

答案 3 :(得分:0)

我有类似的要求并写了这个扩展方法:

internal static IEnumerable<T> Merge<T>(this IEnumerable<T> left, 
  IEnumerable<T> right, 
  Func<T, T, T> resolveConflictFunc,
  IEqualityComparer<T> equalityComparer)
{
    equalityComparer = equalityComparer ?? EqualityComparer<T>.Default;

    return left.Join(right, x => x, x => x, resolveConflictFunc, equalityComparer)
       .Union(left, equalityComparer)
       .Union(right, equalityComparer);    
}

使用该方法,解决方案是:

firstList.Merge(secondList,
                (left, right) => right) // conflict resolution function (takes the right one if exists in both)

在这种情况下,通过从第二个集合中获取项目来解决冲突。该实现允许您注入更复杂的冲突解决逻辑。

结果是一个组合的不同列表。

我进行了一些性能测试,尝试使用hashset方法以及一些LINQ方法。这种实现最终成为最快和最简单的。