X#列表的深度差异

时间:2013-02-04 15:26:34

标签: c# algorithm data-structures

我查看过这些问题,这些问题没有给我我想要的内容:Comparing arrays in C#Compare Two Arrays Of Different Lengths and Show Differences

我有未知数量的List个未知长度的对象,因此可能有2个,10个等列表。

我想过使用类似结构但是意识到虽然它可以确定所有列表是否相等,但它不会告诉我“列表2有元素A而不是元素B,列表3缺少元素C,列表7有一个额外的元素D.

最后,元素是对象,所以我必须实现一个Equals()函数来比较2个元素的相等性。例如,元素可以是car个对象,其中包含制造商的string和价格的int

1 个答案:

答案 0 :(得分:1)

好的,所以你想要查找每个列表,并确定它至少有一个列表中没有的项目,以及至少另一个列表中没有的所有项目。< / p>

首先要找到所有列表中的所有项目;这是每个清单的“交集”。

一旦你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中的其他set操作,所以它将依赖于每个项的GetHashCode方法,因此它必须具有适当的实现该对象的Equals方法。