Is there a built in linq method thing I can use to find out if two sequences contains the same items, not taking the order into account?
For example:
{1, 2, 3} == {2, 1, 3} {1, 2, 3} != {2, 1, 3, 4} {1, 2, 3} != {1, 2, 4}
You have the SequenceEquals, but then I would have to Order both sequences first, wouldn't I?
There are quite a few ways. Assume A and B is IEnumerable.
!A.Except(B).Any() && !B.Except(A).Any() A.Count() == B.Count() && A.Intersect(B).Count() == B.Count() etc
If you don't care about duplicates (i.e. you'd consider {1, 2, 3}
to be equal to {1, 2, 3, 2}
) then:
new HashSet<int>(A).SetEquals(B)
(Or whatever type is the element type instead of int
).
Otherwise:
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; }
Keep a tally of each element in the first sequence, then check the second against it. The moment you have one too many in the second sequence you can return false, otherwise if you have nothing left in the dictionary of tallies they are equal, or false if there's any elements left.
Rather than the two O(n log n) sorts of using OrderBy()
followed by the O(n) comparison, you've an O(n) operation building the set of tallies, and an O(n) check against it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With