it-swarm-pt.tech

Selecione distinto usando linq

Eu tenho uma lista de classe de classe

public class LinqTest
{
public int id { get; set; }
public string value { get; set; }
}


List<LinqTest> myList = new List<LinqTest>();
myList.Add(new LinqTest() { id = 1, value = "a" });
myList.Add(new LinqTest() { id = 1, value = "b" });
myList.Add(new LinqTest() { id = 2, value = "c" });

Eu preciso selecionar apenas os id distintos dessa lista. ou seja, minha lista resultante deve conter apenas

[{id=1,value="a"},{ id = 2, value = "c" }]

Como posso fazer isso com o linq?

Editar

Entrada,

id      value
1        a
1        b
2        c
3        d
3        e

A saída deve ser

id      value
1        a
2        c
3        d

ou seja, se houver uma repetição de id, o resultado deve levar apenas a primeira ocorrência.

222
Anoop Joshi
myList.GroupBy(test => test.id)
      .Select(grp => grp.First());

Edit: como obter este IEnumerable<> em um List<> parece ser um mistério para muitas pessoas, você pode simplesmente escrever:

var result = myList.GroupBy(test => test.id)
                   .Select(grp => grp.First())
                   .ToList();

Mas normalmente é melhor trabalhar com o IEnumerable em vez de IList, já que o Linq acima é avaliado com preguiça: ele não faz todo o trabalho até que o enumerável seja iterado. Quando você chama ToList, ele percorre todo o enumerável, forçando todo o trabalho a ser feito antecipadamente. (E pode demorar um pouco se o seu enumerável for infinitamente longo).

O outro lado deste conselho é que, cada vez que você enumera tal IEnumerable, o trabalho para avaliá-lo deve ser feito novamente. Então você precisa decidir para cada caso se é melhor trabalhar com o IEnumerable preguiçosamente avaliado ou percebê-lo em um List, Set, Dictionary ou algo mais.

453
Paul Ruane

Usando morelinq você pode usar DistinctBy:

myList.DistinctBy(x => x.id);

Caso contrário, você pode usar um grupo:

myList.GroupBy(x => x.id)
      .Select(g => g.First());
104
Daniel Hilgarth

Você deve substituir Equals e GetHashCode de maneira significativa, neste caso, para comparar o ID:

public class LinqTest
{
    public int id { get; set; }
    public string value { get; set; }

    public override bool Equals(object obj)
    {
        LinqTest obj2 = obj as LinqTest;
        if (obj2 == null) return false;
        return id == obj2.id;
    }

    public override int GetHashCode()
    {
        return id;
    }
}

Agora você pode usar Distinct:

List<LinqTest> uniqueIDs = myList.Distinct().ToList();
52
Rango
myList.GroupBy(i => i.id).Select(group => group.First())
23
Tim Rogers