25

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.

8
  • from x in a from y in b where x == y select x == y but its not correct... can not store in a Boolean variable Commented May 26, 2010 at 13:22
  • Does each array have unique values? When you consider two arrays to be the same? if they have the same elements? the same elements in the same order? Commented May 26, 2010 at 13:23
  • Are you looking for a single bool answer if the two are perfectly the same or are you looking for a check to see if each element is the same as its partner. Commented May 26, 2010 at 13:24
  • not in same order... but two arrays should have equal size Commented May 26, 2010 at 13:24
  • 7
    are these equals? { "a", "a", "b" } , { "a", "b", "b" } are these equals? { "a", "b", "a" } , { "a", "a", "b" } Commented May 26, 2010 at 13:26

6 Answers 6

34
string[] a = { "a", "b" };
string[] b = { "a", "b" };

return (a.Length == b.Length && a.Intersect(b).Count() == a.Length);

After some performance testing:

  • Over 10,000 small strings - 5ms
  • Over 100,000 small strings - 99ms
  • Over 1,000,000 small strings - Avg. 601ms
  • Over 100,000 ~500 character strings - 190ms
Sign up to request clarification or add additional context in comments.

9 Comments

but i don't think that performance is ok. intersection is not cheap operation
@Andrey - It depends on the size of the list as well.
Syntactically, I'd say return (a.Length == b.Length && a.Intersect(b).Count() == a.Length), but that's just me.
@Kyle Rozendo: But wait, is this meeting the OP's requirements? It hasn't been stated explicitly, but I would've assumed the OP is looking for a method to check whether the given arrays have the same elements in the same order. Checking a.Intersect(b).Count() is only going to ensure they have the same elements, without checking the order.
However wont this method fail for cases where there are duplicate elements(in both arrays).The intersect operation being a set operation may only retain distinct elements.So if you compare it with Array.length the comparison may fail.
|
27

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);

2 Comments

What do you mean, "it is order independant" ? SequenceEqual is NOT order independant. In your second code sample, it will return false
Not downvoting, but this doesn't answer the question. As per the op: not in same order... but two arrays should have equal size
5

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.

Comments

4

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" };
    

2 Comments

If you compare their sizes first would you need to both containsAll operation?
@Scott, Yes. Consider a = { "a", "b", "c" }; b = { "c", "a". "a" }; same length but the unique items in b are a subset of those in a
4

This works correctly with duplicates and check each element

a.Length == b.Length && !a.Where((t, i) => t != b[i]).Any()

Comments

3
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)));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.