Reputation: 14692
I've two arrays like
string[] a = { "a", "b", "c" };
string[] b = { "a", "b", "c" };
I need to compare the two arrays using LINQ.
The comparison should take place only if both arrays have same size. The data can be in any order and still return true if all values of a[] and all values of b[] are the same.
Upvotes: 25
Views: 41484
Reputation: 2879
This works correctly with duplicates and check each element
a.Length == b.Length && !a.Where((t, i) => t != b[i]).Any()
Upvotes: 4
Reputation: 31
IDictionary<int, object> a = new Dictionary<int, object>();
IDictionary<int, object> b = new Dictionary<int, object>();
a.Add(1, "1");
a.Add(2, 2);
a.Add(3, "3");
b.Add(3, "3");
b.Add(1, "1");
b.Add(2, 2);
Console.WriteLine(a.All(i => b.Contains(i)) && b.All(i => a.Contains(i)));
Upvotes: 3
Reputation: 6993
if order doesn't matter or there can be duplicates, then perhaps:
public static class IEnumerableExtensions
{
public static bool HasSameContentsAs<T>(this ICollection<T> source,
ICollection<T> other)
{
if (source.Count != other.Count)
{
return false;
}
var s = source
.GroupBy(x => x)
.ToDictionary(x => x.Key, x => x.Count());
var o = other
.GroupBy(x => x)
.ToDictionary(x => x.Key, x => x.Count());
int count;
return s.Count == o.Count &&
s.All(x => o.TryGetValue(x.Key, out count) &&
count == x.Value);
}
}
usage:
string[] a = { "a", "b", "c" };
string[] b = { "c", "a", "b" };
bool containSame = a.HasSameContentsAs(b);
some use cases:
different lengths (expect false)
string[] a = { "a", "b", "c" };
string[] b = { "b", "c" };
different order (expect true)
string[] a = { "a", "b", "c" };
string[] b = { "b", "c", "a" };
also works if the inputs can contain duplicate items, though it isn't clear from the question whether that characteristic is desired or not, consider:
duplicated items have same count (expect true)
string[] a = { "a", "b", "b", "c" };
string[] b = { "a", "b", "c", "b" };
duplicated items with different counts (expect false)
string[] a = { "a", "b", "b", "b", "c" };
string[] b = { "a", "b", "c", "b", "c" };
Upvotes: 4
Reputation: 15867
I think this will always be an O(n log n) operation, so I'd just sort both arrays and compare them e.g. using SequenceEqual.
Upvotes: 5
Reputation: 1208
Not sure about the performance, but this seems to work.
string[] a = { "a", "b", "c" };
string[] b = { "a", "b", "c" };
bool result = a.SequenceEqual(b);
Assert.AreEqual(true, result);
However, it is not order independent so it does not fulfill the OP's requirement.
string[] a = { "a", "b", "c" };
string[] b = { "a", "c", "b" };
bool result = a.SequenceEqual(b);
Assert.AreEqual(false, result);
Upvotes: 27
Reputation: 25287
string[] a = { "a", "b" };
string[] b = { "a", "b" };
return (a.Length == b.Length && a.Intersect(b).Count() == a.Length);
After some performance testing:
Upvotes: 34