2013-08-16 2 views
3

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

У меня есть список элементов, например:

BOB 5 
Brian 5 
Sam 6 
James 7 
Emily 8 
Sandra 8 
Michael 8 

Это в List<MyObject>

Я хочу, чтобы отфильтровать список, так что только один пункт за ID, выбрав первый с уникальный идентификатор.

я должен закончить с

BOB 5 
Sam 6 
James 7 
Emily 8 

У меня возникают проблемы с разработкой чистый способ сделать это. Есть идеи?

+1

Вероятно GroupBy в сочетании с .Первым() должен работать, но я не могу сформулировать :( –

+0

Как вы знаете, чтобы выбрать Боб вместо Брайана я имею в виду? , вы говорите «ели t ", но есть ли что-то, что квалифицируется как первое? Datetime stamp, в алфавитном порядке ... – SQLMason

+0

Вы видели это: http://stackoverflow.com/questions/489258/linq-distinct-on-a-particular-property? –

ответ

7

Использование GroupBy и First комбинированный метод:

var results = source.GroupBy(x => x.Id).Select(g => g.First()).ToList(); 

Или как синтаксис на основе запроса:

var results = (from i in source 
       group i by i.Id into g 
       select g.First()).ToList(); 
+0

Мастер, работает угощение. Благодаря! Еще один для набора инструментов. – NibblyPig

1

Я считаю, что правильный путь заключается в реализации IEquatable

Затем с помощью .Distinct()

Вот ссылка, как его использовать. Таким образом, у вас больше контроля над тем, как обрабатывается первый элемент.

http://msdn.microsoft.com/en-us/library/bb348436.aspx

+1

Вот вопрос о том, как переопределить [IEquatable] (http://stackoverflow.com/questions/3897672/linq-object-equality-and-how-to-properly-override-it?rq=1) – SQLMason

0

Вам нужен лучший Distinct метод, который может сделать 'отличается от ключа.

public static IEnumerable<TSource> Distinct<TSource,TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) 
{ 
    var seen = new HashSet<TKey>(); 
    foreach(var x in source) 
    { 
     var key = keySelector(x); 
     if (seen.Add(key);) 
      yield return x; 
    } 
} 
+0

О несвязанных обратите внимание, пожалуйста, не [одобрять предложенные изменения] (http://stackoverflow.com/review/spected-edits/2763311), используя обратные ссылки для акцента, но отклоняйте их или улучшайте их - см., например, [здесь] (http://meta.gaming.stackexchange.com/q/7437/88) почему –

+0

Несомненно, это имеет смысл –

+0

Спасибо за понимание :) –

0

Это должно быть довольно быстро:

int c = 0; 
var results = source.Where(i => 
{ 
    if (i.Id > c) 
    { 
     c = i.Id; 
     return true; 
    } 
    else 
     return false; 
}).ToList(); 
0

(Возможно) более эффективен, чем GroupBy/First комбо, но это требует особого нулевое значение для ID (-1), и что все элементы с таким же ID быть сгруппированы в списке:

 int currentID = -1; 
     var unique = list.Where(x => 
     { 
      if (currentID != -1 && currentID == x.ID) 
       return false; 

      currentID = x.ID; 
      return true; 
     }); 
Смежные вопросы