【问题标题】:Linq, select differences between two lists, select same between same list, and select duplicates same listLinq,选择两个列表之间的差异,相同列表之间选择相同,并选择重复相同列表
【发布时间】:2013-05-02 15:59:01
【问题描述】:

我想知道在 LINQ 中是否有可能实现以下方面的目标:

newList: { [1], [2] }
oldList: { [2], [3], [4], [5] }
resultantList = { [1], [2, 2], [3], [4], [5] }

好吧,那是过于简单化了。让我们说:

Class A
{
    public string Name;
    public IList<B> Items;
    public bool Equals(A obj)
    {
         return obj.Name == Name;
    }
}


newList<A> = {{ Name = "A", Items[1]}, { Name = "B", Items[1] }}
oldList<A> = {{ Name = "C", Items[2]}, { Name = "A", Items[2] }, { Name = "D", Items[1] }, { Name = "E", Items[1] },}
mergedList<A> = {{ Name = "A", Items[3]}, { Name = "B", Items[1]}, { Name = "C", Items[2]}, { Name = "D" , Items[1]}, { Name = "E" , Items[1]}}

请注意,对于 Name="A" 的实例,该列表实际上是两个列表的合并列表。顺序无关紧要,实际上相等更复杂。

我希望在类型上实现这一点(即以下工作,但效率低下):

var fragments = newGeometryFragments.Except(oldGeometryFragments).ToList();
fragments.AddRange(oldGeometryFragments.Except(newGeometryFragments).ToArray());
var mergedFragments = (from newGeometry in newGeometryFragments
                       from oldGeometry in oldGeometryFragments
                       where newGeometry.Equals(oldGeometry)
                       select MergeGeometryFragments(newGeometry, oldGeometry)).ToArray();
 fragments.AddRange(mergedFragments);

【问题讨论】:

  • 列表中项目的顺序是否相关?
  • 搜索 Linq“完全外连接”
  • 所以你基本上想要一个联合,但是由于在一个二元素列表中而显示了重复的值?
  • 订单不相关。基本上我想要的是一个合并,它将两个列表中的项目连接起来,并且它检测到的“合并”项目是等效的(即 MergeGeometryFragments 方法)。
  • 这几乎是一个联盟。只有我希望它在它检测到的项目上调用一个方法,并返回一组合并的项目。

标签: c# linq list merge equality


【解决方案1】:

假设您已经填写了oldListnewList,您可以使用以下代码:

newList.Union(oldList) // unite the collections
   .GroupBy(x => x /*, ComparerInstance*/) // will group by unique elemens
   .Select(x => x.ToList()) // or .ToArray(), convert each group to array or list
   .ToList(); // return a list of lists/arrays

上面的代码将生成一个集合列表。每个集合将有一个或多个相等的元素,具体取决于该元素在 newList.Union(oldList) 中出现的次数。

如果您正在使用特定元素并希望控制它们的比较方式(确定相等),请将自定义 IEqualityComparer&lt;YourType&gt; 实例传递给 GroupBy 方法。

【讨论】:

    【解决方案2】:

    你可以使用外连接:

    var oldList = new List<int?> { 2, 3, 4, 5 };
    var newList = new List<int?> { 1, 2 };
    var result = from all in oldList.Union(newList).OrderBy(num => num)
                 join o in oldList on all equals o into gjOld
                 from oldOuter in gjOld.DefaultIfEmpty()
                 join n in newList on all equals n into gjNew
                 from newOuter in gjNew.DefaultIfEmpty()
                 select new { newVal = newOuter, oldVal = oldOuter };
    

    当您实现 EqualsGetHashCode 或实现自定义 IEqualityComparer&lt;T&gt; 时,这也适用于自定义类。那么Nullable&lt;int&gt;的把戏也不需要了

    Demo

    newVal: 1   oldVal: 
    newVal: 2   oldVal: 2
    newVal:     oldVal: 3
    newVal:     oldVal: 4
    newVal:     oldVal: 5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 1970-01-01
      • 2018-07-09
      相关资源
      最近更新 更多