Linq,选择两个列表之间的差异,选择相同列表之间的相同,并选择重复相同的列表
本文关键字:列表 选择 之间 两个 Linq | 更新日期: 2023-09-27 18:12:32
我想知道是否有可能在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);
您可以使用以下代码,假设您已经填充了oldList
和newList
:
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<YourType>
实例传递给GroupBy
方法。
您可以使用外部连接:
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 };
当您实现Equals
和GetHashCode
或实现自定义IEqualityComparer<T>
时,这也适用于自定义类。那么Nullable<int>
技巧也是不必要的
newVal: 1 oldVal:
newVal: 2 oldVal: 2
newVal: oldVal: 3
newVal: oldVal: 4
newVal: oldVal: 5