简体   繁体   中英

List.Contains doesn't return true when element exists

I have got a little problem.

I have a list of int arrays that contains of ID (any number) and Count (which can be anything from 0 to 5) which is named playerWordList and second list with IDs only with name words . What I'm trying to do is a function that checks if every ID from second list is present in first (Count doesn't matter) and if it is not present, add element with that missing ID and Count equal to 0.

At the moment, I have a workaround, which is double loop that for every element in second list iterates through every element in first list looking for a match, but I see that there is a method List.Contains that would perfectly match in my problem but it is just not working properly.

I read a few topic on SO about it, but they mainly focus on comparing two elements of custom class, which require overriding Equals and GetHashCode , but I don't know if it applies to my problem in any way, and if it does, then I have no idea how can I override Equals and GetHashCode for int arrays.

Here is my code:

foreach (var word in unit.words)
{
    int[] ex1 = new int[2] { word.id, 0 };
    int[] ex2 = new int[2] { word.id, 1 };
    int[] ex3 = new int[2] { word.id, 2 };
    int[] ex4 = new int[2] { word.id, 3 };
    int[] ex5 = new int[2] { word.id, 4 };
    int[] ex6 = new int[2] { word.id, 5 };

    if (playerWordList.Contains(ex1) ||
        playerWordList.Contains(ex2) ||
        playerWordList.Contains(ex3) ||
        playerWordList.Contains(ex4) ||
        playerWordList.Contains(ex5) ||
        playerWordList.Contains(ex6)) break;
    else
    {
        int[] newWord = new int[2] { word.id, 0 };

        playerWordList.Add(newWord);
    }
}

Contains checks on reference equality . So these object instances should be the same. It doesn't check on value equality . I suspect that you insert other instances of ex1(2,3,4,5) somewhere else and that contains doesn't return true because of the references not being equal.

Hope this clarifies some things.

This will work:

int[] ex1 = new int[2] { word.id, 0 };
playerWordList.Insert(ex1)
if(playerWordList.Contains(ex1))
  // returns true

But if you create and insert ex1 somewhere else and put it in the playerWordList and then in your foreach create "new" instances of ex objects than these are actually different references to different objects (although with the same values, but Contains doesn't compare values but references ;)

You can't override GetHashCode and Equals methods for a built-in type but you can implement an IEqualityComparer for int[] and pass it to Contains method.This is usually the way to go, but if you want a quick way, you can simply use Any method with SequenceEqual :

if(playerWordList.Any(x => x.SequenceEqual(ex1) ||
                           x.SequenceEqual(ex2) ||
                           x.SequenceEqual(ex3) ||
                           x.SequenceEqual(ex4) ||
                           x.SequenceEqual(ex5) ||
                           x.SequenceEqual(ex6))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM