是否有一个内置的linq方法的东西,我可以用来找出两个序列是否包含相同的项目,而不考虑订单?
例如:
{1, 2, 3} == {2, 1, 3}
{1, 2, 3} != {2, 1, 3, 4}
{1, 2, 3} != {1, 2, 4}
Run Code Online (Sandbox Code Playgroud)
你有SequenceEquals,但是我必须首先对两个序列进行排序,不是吗?
lep*_*pie 41
有很多方法.假设A和B是IEnumerable.
!A.Except(B).Any() && !B.Except(A).Any()
A.Count() == B.Count() && A.Intersect(B).Count() == B.Count()
etc
Run Code Online (Sandbox Code Playgroud)
Jon*_*nna 10
如果您不关心重复项(即您认为{1, 2, 3}
等于{1, 2, 3, 2}
),则:
new HashSet<int>(A).SetEquals(B)
Run Code Online (Sandbox Code Playgroud)
(或任何类型是元素类型而不是int
)。
除此以外:
public static bool SequenceEqualUnordered<T>(IEnumerable<T> first, IEnumerable<T> second)
{
if (first == null)
return second == null; // or throw if that's more appropriate to your use.
if (second == null)
return false; // likewise.
var dict = new Dictionary<T, int>(); // You could provide a IEqualityComparer<T> here if desired.
foreach(T element in first)
{
int count;
dict.TryGetValue(element, out count);
dict[element] = count + 1;
}
foreach(T element in second)
{
int count;
if (!dict.TryGetValue(element, out count))
return false;
else if (--count == 0)
dict.Remove(element);
else
dict[element] = count;
}
return dict.Count == 0;
}
Run Code Online (Sandbox Code Playgroud)
记录第一个序列中的每个元素,然后根据它检查第二个元素。如果第二个序列中的元素过多,则可以返回 false,否则,如果计数字典中没有任何内容,则它们是相等的,如果还有任何元素,则返回 false。
不是两种 O(n log n) 类型的使用OrderBy()
后跟 O(n) 比较,而是使用 O(n) 操作构建计数集,并对其进行 O(n) 检查。
小智 9
有两个IEnumerables(A和B):
bool equal = (A.Count() == B.Count() && (!A.Except(B).Any() || !B.Except(A).Any()))
Run Code Online (Sandbox Code Playgroud)
我认为这比Except(A).Count更好,因为不会评估整个Excep.只要在"除外"中找到一个元素,它就会停止.使用Count,可以评估整个Except.除此之外,我们可以避免对这些代价高昂的评估,除非首先检查Count属性.如果计数不相等,那么我们检查Excepts.