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.
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.
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());
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();
myList.GroupBy(i => i.id).Select(group => group.First())