Ik heb een klaslijst van klas
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" });
Ik hoef alleen de verschillende id’s uit die lijst te selecteren.
dat wil zeggen, mijn resulterende lijst mag alleen
. bevatten
[{id=1,value="a"},{ id = 2, value = "c" }]
Hoe kan ik dit doen met linq?
Bewerken
Invoer,
id value
1 a
1 b
2 c
3 d
3 e
Uitvoer zou moeten zijn,
id value
1 a
2 c
3 d
dwz, als er een herhaling is van id
, mag het resultaat alleen de eerste keer voorkomen.
Antwoord 1, autoriteit 100%
myList.GroupBy(test => test.id)
.Select(grp => grp.First());
Bewerken: aangezien het voor veel mensen een mysterie lijkt om deze IEnumerable<>
in een List<>
te krijgen, kun je gewoon schrijven:
var result = myList.GroupBy(test => test.id)
.Select(grp => grp.First())
.ToList();
Maar men is vaak beter af met de IEnumerable
in plaats van IList
, aangezien de Linq hierboven lui wordt geëvalueerd: het doet eigenlijk niet al het werk totdat de opsombaar wordt herhaald. Als je ToList
aanroept, loopt het eigenlijk de hele opsomming, waardoor al het werk vooraf wordt geforceerd. (En het kan even duren als je opsomming oneindig lang is.)
De keerzijde van dit advies is dat elke keer dat je zo’n IEnumerable
opsomt, het werk om het te evalueren opnieuw moet worden gedaan. Je moet dus voor elk geval beslissen of het beter is om te werken met de lui geëvalueerde IEnumerable
of om het te realiseren in een List
, Set
, Dictionary
of zo.
Antwoord 2, autoriteit 23%
Met morelinqkun je DistinctBy
:
gebruiken
myList.DistinctBy(x => x.id);
Anders kun je een groep gebruiken:
myList.GroupBy(x => x.id)
.Select(g => g.First());
Antwoord 3, autoriteit 11%
U moet Equals
en GetHashCode
zinvol overschrijven, in dit geval om de ID te vergelijken:
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;
}
}
Nu kunt u Distinct
gebruiken:
List<LinqTest> uniqueIDs = myList.Distinct().ToList();
Antwoord 4, autoriteit 5%
myList.GroupBy(i => i.id).Select(group => group.First())