Pie*_*aud 20 c# linq ienumerable set-theory
我有两个集合a和b.我想计算a或者b两者中的项目集合,而不是两者中的项目集合(逻辑异或).有了LINQ,我可以想出这个:
IEnumerable<T> Delta<T>(IEnumerable<T> a, IEnumerable<T> b)
{
    return a.Except (b).Union (b.Except (a));
}
我想知道是否还有其他更有效或更紧凑的方法来产生两个集合之间的差异.
编辑1:Jon Skeet发布了第一个解决方案,它不依赖于a来保留项目的顺序HashSet.我想知道是否有其他方法可以保持输出的顺序a和b输出.
Jon*_*eet 26
HashSet<T>直接使用- 它有一个SymmetricExceptWith方法:
HashSet<T> data = new HashSet<T>(a);
data.SymmetricExceptWith(b);
编辑:如果你想维持订单,这里有一个替代方案:
HashSet<T> data = new HashSet<T>(a);
data.IntersectWith(b);
foreach (T t in a.Concat(b))
{
    if (!data.Contains(t))
    {
        yield return t;
    }
}
这有以下重要区别:
a和b被重复两次以上.在某些情况下,这可能是一件非常糟糕的事情 - 您可以调用ToList它们中的每一个来保留缓冲区.如果有任何重复a或b,他们将得到多次.如果你想避免这种情况,你可以保留一组已经产生的值.在这一点上,它将等同于:
a.Concat(b).Except(a.Intersect(b))
尽管如此,这仍然只是两个设置操作,而不是原始代码中的三个操作.
给定a.除了(b)和b.除了(a)是不相交的,你可以使用concat代替union,保存集合运算符(并且concat更有效).
return a.Except (b).Concat (b.Except (a));
这仍然会在每个列表中运行两次.
| 归档时间: | 
 | 
| 查看次数: | 9113 次 | 
| 最近记录: |