6

I am comparing two lists by the following way:

var listOne = new List<int>{1,2,3,4,5};
var listTwo = new List<int>{1,2,3,4,5,7};
bool isEqual = false;

foreach (var item in listOne)
{
    if(listTwo.Contains(item))
    {
        isEqual = true;
    }
    else
    {
        isEqual = false;
        break;
    }
}

if(listOne.Count == listTwo.Count && isEqual == true)
{
    Console.WriteLine("Equal list");
}
else
{
    Console.WriteLine("Not Equal list");
}

Is there any easy way to do this?

janw
  • 8,758
  • 11
  • 40
  • 62
  • 7
    if (listOne.Except(listTwo).Any()) [LINQ - compare two lists](http://stackoverflow.com/questions/9524681/linq-compare-two-lists) :) – Paritosh Jul 04 '13 at 07:39
  • 2
    Do you care about the order of the items? like, does {1,2} = {2,1} for your matter? – Roee Gavirel Jul 04 '13 at 07:41
  • @Paritosh, I'm not sure it will work. Except returns set difference which define: `The set difference of two sets is defined as the members of the first set that do not appear in the second set.`. So in the given case the except will be empty while the List are not equal. – Roee Gavirel Jul 04 '13 at 07:52
  • @RoeeGavirel: Yes, but OP doesn't want to know if two lists are equal( as opposed to what his variable names and messages suggest) but he wants to know if the second list is contained in the first. At least that does his old code he wants to refactor. If you want to check both ways(and you yare not interested in the order) you can still use `Enumerable.Except`. Have a look at the second approach in [my answer](http://stackoverflow.com/a/17464472/284240). – Tim Schmelter Jul 04 '13 at 08:00
  • 1
    {1,2} = {2,1} does not matter @RoeeGavirel –  Jul 04 '13 at 08:01
  • 1
    @IITDU: But your accepted answer does **not** ignore the order. So it's different to your code. – Tim Schmelter Jul 04 '13 at 08:06
  • 1
    Actually I was not sure the order matter or does not matter. Any way .. I Edited it. – Atish Kumar Dipongkor Jul 04 '13 at 08:18
  • I did it before your editing and that's why I accepted your answer @AtishDipongkor –  Jul 04 '13 at 08:39

5 Answers5

22

very easy way

    var listOne = new List<int>{1,2,3,4,5};
    var listTwo = new List<int>{1,2,3,4,5,7};

    if (listOne.SequenceEqual(listTwo))
            {
                Console.WriteLine("Equal list");
            }
            else
            {
                Console.WriteLine("Not Equal list");
            }

if order does not matter then the solution will be

    var listOne = new List<int>{1,2,3,4,5};
    var listTwo = new List<int>{1,2,3,4,5,7};

     if (listOne.OrderBy(m => m).SequenceEqual(listTwo.OrderBy(m => m)))
        {
            Console.WriteLine("Equal list");
        }
        else
        {
            Console.WriteLine("Not Equal list");
        }
Atish Kumar Dipongkor
  • 10,220
  • 9
  • 49
  • 77
  • 1
    He hasn't mentioned that he wants to know if both have the same order of items. – Tim Schmelter Jul 04 '13 at 07:45
  • 2
    This is not correct!! `{1, 2}` and `{2, 1}` should return `true`. – Ahmed KRAIEM Jul 04 '13 at 07:45
  • 1
    @AhmedKRAIEM - OP didn't specify that directly, but his code would suggest that, yes. – Corak Jul 04 '13 at 07:56
  • @Corak: Actually OP _has_ specified that directly, in a comment to his question. – Tim Schmelter Jul 04 '13 at 08:09
  • Actually I was not sure the order matter or does not matter. Any way .. I Edited it. – Atish Kumar Dipongkor Jul 04 '13 at 08:18
  • @TimSchmelter - yes, about 5 minutes *after* my comment. ^_^ – Corak Jul 04 '13 at 08:42
  • @AtishDipongkor: Your last edit is inefficient and might even be incorrect because it modifies both collections. `listOne.Sort()` will change the order of the items even if that is not desired. Just use `Except` which is also more efficient since it uses sets. – Tim Schmelter Jul 04 '13 at 08:55
  • Thanks @AtishDipongkor and @ Tim Schelter. I wanted to compare two list(where the order may matter or may not matter). But I didn't care what listOne.Sort() is doing. Thanks again. –  Jul 04 '13 at 09:06
  • @TimSchmelter you gave three ways to solve this problem that means you are also not sure what IITDU wants. So ..... How could I be??? Thanks – Atish Kumar Dipongkor Jul 04 '13 at 09:15
  • @AtishDipongkor: I was sure since he showed his old (working) code. That is what i have shown in my first approach. By the way, every approach is explained. So if he wants to change the logic he can use the appropriate way. – Tim Schmelter Jul 04 '13 at 09:16
  • Also in your unit tests you will want to use CollectionAssert.AreEqual(list1, list2); – GodsCrimeScene Jul 19 '13 at 17:39
14

If you are not interested in the same order you can use Except which is very efficient:

bool isEqual = !listOne.Except(listTwo).Any();

If you want to know if both contain the same items(still ignoring the order):

if (listOne.Count > listTwo.Count)
    isEqual = !listOne.Except(listTwo).Any();
else
    isEqual = !listTwo.Except(listOne).Any();

If you want to check if both lists contain the same items in the same order:

bool isEqual = listOne.SequenceEqual(listTwo);

If you are using custom types you need to override Equals and GetHashCode, otherwise you just compare by reference.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
4

I believe the easiest way is to use Enumerable.SequenceEqual method.

Determines whether two sequences are equal by comparing the elements by using the default equality comparer for their type.

bool equal = listOne.SequenceEqual(listTwo);

The SequenceEqual<TSource>(IEnumerable<TSource>, IEnumerable<TSource>) method enumerates the two source sequences in parallel and compares corresponding elements by using the default equality comparer for TSource, Default. The default equality comparer, Default, is used to compare values of the types that implement the IEqualityComparer<T> generic interface.

As Tim pointed, if your items are not ordered, using Except method looks better. For example;

bool equal = !listTwo.Except(listOne).Any();
Community
  • 1
  • 1
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
0

Assuming you are not interested in the order, you can use OrderBy and SequenceEqual:

public static bool ListsEquals(List<int> listOne, List<int> listTwo)
{
    if (listOne.Count != listTwo.Count)
        return false;

    if (!listOne.OrderBy(x => x).SequenceEqual(listTwo.OrderBy(x => x)))
        return false;
}

Or Intersect:

public static bool ListsEquals(List<int> listOne, List<int> listTwo)
{
    if (listOne.Count != listTwo.Count)
        return false;

    if (listOne.Intersect(listTwo).Count() != listOne.Count)
        return false;

    return true;
}

Or Except and Any

public static bool ListsEquals(List<int> listOne, List<int> listTwo)
{
    if (listOne.Count != listTwo.Count)
        return false;

    if (!listOne.Except(listTwo).Any())
        return false;

    return true;
}
Ahmed KRAIEM
  • 10,267
  • 4
  • 30
  • 33
0

If Order of item in the list matter you can use the SequenceEqual as many advise here.

If the order doesn't matter you should sort the lists before, and I would check the count of them before the sorting to avoid sorting and comparing if there are in different size:

var listOne = new List<int>{1,2,3,4,5};
var listTwo = new List<int>{1,2,3,4,5,7};

var equal = (listOne.Count == listTwo.Count);

if (equal)
{
    listOne.Sort();
    listTwo.Sort();
    equal = listOne.SequenceEqual(listTwo)
}

if (equal)
{
     Console.WriteLine("Equal list");
}
else
{
     Console.WriteLine("Not Equal list");
}
Roee Gavirel
  • 18,955
  • 12
  • 67
  • 94