比较.Net和动作中的两个列表,具体取决于项目所在的列表

时间:2013-05-20 09:03:40

标签: .net extension-methods ienumerable

我有一个保存更改列表的网页,因此在保存操作中我有两个列表,一个包含新值,另一个包含现有值。

我想:

  • 遍历两个列表,联合并重复使用。
  • 在新列表中而不在现有列表中的位置我想添加新项目。
  • 两个列表中的哪个位置我想跳过它。
  • 在现有列表中但不在新列表中的位置我想删除该项目。

很容易敲出一个方法来执行此操作,例如:

public static IEnumerable<UnionCompared<T>> UnionCompare<T>(
    this IEnumerable<T> first, IEnumerable<T> compare, IEqualityComparer<T> comparer = null)
{
    // Create hash sets to check which collection the element is in
    var f = new HashSet<T>(first, comparer);
    var s = new HashSet<T>(compare, comparer);

    // Use Union as it dedupes
    var combined = first.Union(compare, comparer);
    foreach (var c in combined)
    {
        // Create a type that has the item and a flag for which collection it's in
        var retval = new UnionCompared<T>
        {
            Item = c,
            InFirst = f.Contains(c),
            InCompare = s.Contains(c)
        };

        yield return retval;
    }
}

然而,这更像是重新发明轮子。那里有什么东西已经做到了吗?这似乎是其他人已经解决的问题。

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

如果您的类型T具有唯一键(字符串或ID),那么我建议提取所有键,将它们放入 string 类型的 List 中int 并使用Intersect and Except扩展方法获取重复项/缺失/新项目或编写IEqualityComprer - 自定义类型 T 的实现,然后再次使用列出扩展方法。

最后,我认为此解决方案将采用与您的实现相同或更少的代码量。我总是试图使用框架已经提供的东西。 : - )