2015-02-20 4 views
1

У меня есть небольшая проблема.List.Contains не возвращает true, когда существует элемент

У меня есть список массивов int, содержащих идентификатор (любое число) и граф (который может быть чем угодно от 0 до 5), который имеет имя playerWordList и второй список с идентификаторами только с именем words. То, что я пытаюсь сделать, - это функция, которая проверяет, присутствует ли каждый идентификатор из второго списка в первом (граф не имеет значения), а если его нет, добавьте элемент с этим отсутствующим идентификатором и количеством, равным 0.

На данный момент у меня есть обходное решение, которое представляет собой двойной цикл, который для каждого элемента во втором списке выполняет итерацию через каждый элемент в первом списке, который ищет совпадение, но я вижу, что существует метод List.Contains, который бы идеально соответствовал моей проблеме но он просто не работает должным образом.

Я прочитал несколько тем об этом, но в основном они сосредоточены на сравнении двух элементов пользовательского класса, которые требуют переопределения Equals и GetHashCode, но я не знаю, относится ли это к моей проблеме каким-либо образом и если это так, то я понятия не имею, как я могу переопределить Equals и GetHashCode для массивов int.

Вот мой код:

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

ответ

0

вы не можете переопределить GetHashCode и Equals метод для встроенного типа, но вы можете реализовать IEqualityComparer для int[] и передать его в Contains method.This, как правило, путь, но если вы хотите быстро, то вы можете просто использовать Any метод с SequenceEqual:

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

Что это за "x => x.SequenceEqual (ex1)" thingy? Я вижу это очень часто, но я не могу его искать, потому что только в нем есть стрелка и кажется полезным –

+0

SequenceEqual проверяет, имеют ли две последовательности одинаковые элементы в том же порядке. –

+0

Хорошо, но я спрашивал об этом «=>». Это LINQ? –

0

Содержит проверки на равенство ссылок. Таким образом, эти экземпляры объектов должны быть одинаковыми. Он не проверяет на Значение равенства. Я подозреваю, что вы вставляете другие экземпляры ex1 (2,3,4,5) где-то в другом месте и которые не возвращают true из-за того, что ссылки не равны.

Надеюсь, это прояснит некоторые вещи.

Это будет работать:

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

Но если вы создаете и вставить EX1 где-нибудь еще, и положить его в playerWordList, а затем в вашем Еогеасп создать «новые» экземпляры бывших объектов, чем они являются на самом деле разные ссылки различные объекты (хотя и с теми же значениями, но Contains не сравнивают значения, но ссылки;)

+0

Так что, если я правильно понял, содержит метод, как правило, бесполезно в моем случае, если я не переопределяю/не модифицирую его, не так ли? –

Смежные вопросы