2010-05-11 3 views
3

Если моя коллекция упорядочена по дате, Distinct() возьмет первый объект в списке соседних дубликатов или не уверен? Я использую IEqualityComparer, который не учитывает поле даты, но я хочу быть уверенным, что последняя дата всегда принимается.Порядок устранения при использовании Distinct() при сборе

+0

Ваш 'IEqualityComparer' должен учитывать все поля, необходимые для проведения различия. –

ответ

5

Вы должны использовать GroupBy:

from s in whatever 
group s by new { s.Field1, s.Field2 } into g 
select g.OrderByDescending(o => o.Date).First() 

EDIT: Вы также можете использовать IEqualityComparer с GroupBy:

whatever.GroupBy(
    s => s,  //Key 
    g => g.OrderByDescending(o => o.Date).First() //Result 
    new MyComparer() 
); 
+0

вместо IEqualitycomparer? – zsharp

+0

Да. – SLaks

2

Не определено, что требуется.

На практике это, вероятно, займет первое место, если вы используете LINQ для объектов, но не должны полагаться на него.

Если вы обращаетесь к базе данных, это зависит от версии базы данных, плана запроса и т. Д. Тогда вы действительно не должны полагаться на это, всегда возвращая первое.

Если вы хотите эту гарантию, вы можете использовать DistinctBy от morelinq и спросить Jon Skeet до guarantee the order for you.

+0

Только LINQ-to-Objects поддерживает IEqualityComparers. – SLaks

+0

@SLaks: Пропустил этот бит. Я наполовину соблазн удалить этот бит из моего ответа, но, возможно, оставьте его, поскольку я считаю, что он предлагает объяснение, почему Distinct не дает гарантии? –

1

В комментариях this answer, Марк Gravell и я обсуждаю перечислим. Отличный метод. Приговор заключается в том, что заказ сохраняется, но документация не гарантирует, что это всегда будет работать.

1

Enumerable.Distinct не определяет, какое значение возвращается, но я не вижу, как было бы разумно возвращать что-либо, кроме первого. Аналогично, хотя порядок не определен, разумно возвращать элементы в том порядке, в котором они появляются в исходной последовательности.

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

Если вы хотите положиться на это неуказанное поведение, вы должны заказать товары по дате (по убыванию) перед использованием Distinct. Кроме того, вы можете использовать группировку, а затем упорядочить каждую группу соответствующим образом.

+0

Помимо использования неопределенного поведения, такой код также будет * вводить в заблуждение *. Если существует разница между экземплярами объектов, которые предпочтительнее других, нельзя, вероятно, не использовать «Distinct». Для меня, когда вы указываете, что хотите получить отдельное подмножество, вы подразумеваете, что семантика идентичности не имеет значения и имеет значение только семантика равенства. – LBushkin

+1

@LBushkin: Используя версию, которая не указывает на сопоставитель равенства, я согласен. Но если вы указываете сопоставитель равенства, вы говорите: «Я хочу элементы, которые различны в этой конкретной характеристике», - и два элемента могут быть легко равны в этом, но различны в других. В целом я думаю, что GroupBy - это более простой способ выразить это, но он может быть менее эффективным. –

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