2016-12-24 2 views
0

У меня есть два List<CustomObject>, называемый list1 и List2быстрый способ сравнить два списка <CustomObject>

public class CustomObject 
{ 
    public string foo { get; set; } 
    public string bar{ get; set; } 
} 

Цель состоит в том, чтобы создать новый список всех записей, которые были изменены/добавлены в list2.

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

Любые идеи?

+0

Вам просто нужно сравнить экземпляры объектов, или вам нужно выполнить глубокое сравнение всех свойств? –

+0

Мне довольно просто нужно сравнить значение foo каждой записи списка. Думаю, это значит, что это так сильно сравнится? – CiriousJoker

+0

Является ли list1 вашим исходным списком, а list2 является текущим списком после изменений и т. Д.? Если вы действительно просите отслеживать, что изменилось в одном списке с течением времени, это совсем другой вопрос (и тот, который имеет более простой ответ, чем сравнение двух списков). – PMV

ответ

1

Добавление другого ответа, чтобы разместить дополнительные НСФО, которые пришли в комментариях:

  1. Объекты могут быть идентифицированы хеш-кодом
  2. Список очень большой, поэтому производительность - это проблема
  3. Идея состоит в том, чтобы сравнить старый список с новым списком, чтобы узнать, появились ли какие-либо новые хеш-коды.

Вы хотите хранить свои объекты в словаре:

var list = new Dictionary<string, CustomObject>(); 

Когда вы добавляете их, предоставить хэш как ключ:

list.Add(customObject.Hash, customObject); 

Для поиска новых:

var difference = new List<CustomObject>(); 
foreach (customObject o in newList) 
{ 
    if (oldList.ContainsKey(o.Hash)) difference.Add(o); 
} 
Log(String.Format("{0} new hashes found.", difference.Count)); 

Используя словарь, вы воспользуетесь способом t ключи хранятся в хеш-таблице. Поиск элемента в хеш-таблице быстрее, чем просто проверка & сравнить вещи. Я полагаю, что это будет O (n * log (n)) вместо O (n^2).

1

Вот традиционный способ сделать это:

public class CustomObject : IComparable 
{ 
    public string foo { get; set; } 
    public string bar{ get; set; } 
    public int CompareTo(CustomObject o) 
    { 
     if (this.foo == o.foo && this.bar == o.bar) return 0; 

     //We have to code for the <and> comparisons too. Could get painful if there are a lot of properties to compare. 
     if (this.Foo == o.Foo) return (this.Bar.CompareTo(o.Bar)); 
     return this.Foo.CompareTo(o.Foo); 
    } 
} 

Затем используйте Linq.Except:

listA.Except(listB) 
+0

Могу ли я спросить, почему CompareTo должен вернуть int?Я нашел [this] (https://msdn.microsoft.com/en-us/library/system.icomparable.compareto (v = vs.110) .aspx), но я не понимаю, как вернуть -1, 0 и 1 меняет что-либо. В настоящее время это всегда приводит к тому, что «невозможно преобразовать ошибку bool в int» – CiriousJoker

+0

Упс забыл эту деталь. Ред. –

+0

Ой, теперь имеет смысл, полностью пропущено, что документация – CiriousJoker

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