X # 列表的深入差异
本文关键字:列表 | 更新日期: 2023-09-27 17:57:24
我看过这些问题,这些问题并没有给我想要的东西: 比较 C# 中的数组并比较两个不同长度的数组并显示差异
我有未知数量的未知长度的List
对象,因此可能有 2、10 等列表。
我考虑过使用类似集合的结构,但意识到虽然它可以确定所有列表是否相等,但它不会告诉我"列表 2 有元素 A 而不是元素 B,列表 3 缺少元素 C,列表 7 有一个额外的元素 D。
最后,元素是对象,所以我必须实现一个 Equals() 函数来比较 2 个元素的相等性。 例如,元素可以是car
对象,这些对象包含制造商的string
和价格的int
。
好的,所以你想去每个列表并确定它拥有的至少一个其他列表中的项目,以及它至少一个其他列表中
没有的项目。要做到这一点,首先要找到所有列表中的所有项目;这是每个列表的"交集"。
一旦你有了这个Except
就会为你完成所有的工作。 给定列表中except
的所有项目都会为您提供交集但不在该特定列表中的项目,列表Except
交集中的项目是交集中缺少的所有项目。
public static IEnumerable<SetDifference<T>> ComputeDifferences<T>(IList<List<T>> lists)
{
if (lists.Count == 0)
yield break;
var intersection = new HashSet<T>(lists.First());
foreach (var list in lists.Skip(1))
{
intersection.IntersectWith(list);
}
var output = new List<SetDifference<T>>();
foreach (var list in lists)
{
yield return new SetDifference<T>(
list: list,
additionalObjects: list.Except(intersection),
missingObjects: intersection.Except(list));
}
}
这是用于提供输出的简单数据持有者。
public class SetDifference<T>
{
public SetDifference(List<T> list, IEnumerable<T> additionalObjects,
IEnumerable<T> missingObjects)
{
List = list;
AdditionalObjects = additionalObjects;
MissingObjects = missingObjects;
}
public List<T> List { get; private set; }
public IEnumerable<T> AdditionalObjects { get; private set; }
public IEnumerable<T> MissingObjects { get; private set; }
}
请注意,由于我使用的是 HashSet
以及 LINQ 中的其他集合操作,因此它将依赖于每个项的 GetHashCode
方法,因此给定该对象的 Equals
方法,它必须具有适当的实现。