Самый быстрый способ сравнить два списка - PullRequest
10 голосов
/ 04 января 2009

У меня есть список (Foo), и я хочу посмотреть, равен ли он другому списку (foo). Какой самый быстрый способ?

Ответы [ 6 ]

24 голосов
/ 04 января 2009

Начиная с 3.5 вы можете использовать функцию LINQ для этого:

List<string> l1 = new List<string> {"Hello", "World","How","Are","You"};
List<string> l2 = new List<string> {"Hello","World","How","Are","You"};
Console.WriteLine(l1.SequenceEqual(l2));

Он также знает о перегрузке, чтобы предоставить свой собственный компаратор

13 голосов
/ 04 января 2009

Вот шаги, которые я бы сделал:

  1. Сделайте object.ReferenceEquals (), если true, а затем вернуть true.
  2. Проверьте счет, если не совпадает, верните false.
  3. Сравните элементы по одному.

Вот несколько советов по методу:

  1. Основывать реализацию на ICollection. Это дает вам счет, но не ограничивает конкретный тип коллекции или содержащийся тип.
  2. Вы можете реализовать метод как метод расширения ICollection.
  3. Вам нужно будет использовать .Equals () для сравнения элементов списка.
1 голос
/ 04 января 2009

Примерно так:

public static bool CompareLists(List<int> l1, List<int> l2)
{
    if (l1 == l2) return true;
    if (l1.Count != l2.Count) return false;
    for (int i=0; i<l1.Count; i++)
        if (l1[i] != l2[i]) return false;
    return true;
}

Может потребоваться дополнительная проверка ошибок (например, проверка на ноль).

0 голосов
/ 20 января 2010

Один ярлык, о котором я не упомянул, заключается в том, что если вы знаете, как создавались списки, вы можете объединить их в строки и сравнить напрямую.

Например ...

В моем случае я хотел предложить пользователю список слов. Я хотел убедиться, что каждое слово начинается с буквы, но после этого оно может содержать буквы, цифры или подчеркивания. Я особенно обеспокоен тем, что пользователи будут использовать тире или начинать с цифр.

Я использую регулярные выражения, чтобы разбить его на 2 списка, и они объединяют их вместе и сравнивают как строки:

    var testList = userInput.match(/[-|\w]+/g)  
        /*the above catches common errors: 
         using dash or starting with a numeric*/
    listToUse = userInput.match(/[a-zA-Z]\w*/g)

    if (listToUse.join(" ") != testList.join(" ")) {
                return "the lists don't match"

Поскольку я знал, что ни один из списков не будет содержать пробелов и что списки содержали только простые строки, я мог соединить их вместе с пробелом и сравнить их.

0 голосов
/ 04 января 2009

Предполагая, что вы хотите знать, равны ли СОДЕРЖАНИЕ (а не просто ссылка на объект списка).

Если вы будете выполнять проверку на равенство гораздо чаще, чем вставки, то может оказаться более эффективным генерировать хеш-код при каждом добавлении значения и сравнивать хеш-коды при выполнении проверки на равенство. Обратите внимание, что вы должны учитывать, важен ли порядок или просто, что списки имеют одинаковое содержимое в любом порядке.

Если вы не часто сравниваете, я думаю, что это, как правило, пустая трата.

0 голосов
/ 04 января 2009

Примерно так, возможно, с помощью Match Action.

public static CompareList<T>(IList<T> obj1, IList<T> obj2, Action<T,T> match)
{
   if (obj1.Count != obj2.Count) return false;
   for (int i = 0; i < obj1.Count; i++)
   {
     if (obj2[i] != null && !match(obj1[i], obj2[i]))
       return false;
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...