Selecteer onderscheiden met linq [duplicate]

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 IEnumerablein 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 ToListaanroept, 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 IEnumerableopsomt, 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 IEnumerableof om het te realiseren in een List, Set, Dictionaryof 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 Equalsen GetHashCodezinvol 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 Distinctgebruiken:

List<LinqTest> uniqueIDs = myList.Distinct().ToList();

Antwoord 4, autoriteit 5%

myList.GroupBy(i => i.id).Select(group => group.First())

Other episodes