643 Stimmen

Duplikate aus einer List<T> in C# entfernen

Jeder haben eine schnelle Methode für de-Duplizierung eine generische Liste in C#?

5 Stimmen

Ist Ihnen die Reihenfolge der Elemente im Ergebnis wichtig? Dies wird einige Lösungen ausschließen.

3 Stimmen

Eine Ein-Zeilen-Lösung: ICollection<MyClass> withoutDuplicates = new HashSet<MyClass>(inputList);

0 Stimmen

Wo würde diese Methode angewendet werden?

49voto

Eric Punkte 640

Ich verwende gerne diesen Befehl:

List<Store> myStoreList = Service.GetStoreListbyProvince(provinceId)
                                                 .GroupBy(s => s.City)
                                                 .Select(grp => grp.FirstOrDefault())
                                                 .OrderBy(s => s.City)
                                                 .ToList();

Ich habe diese Felder in meiner Liste: Id, StoreName, Stadt, PostalCode Ich wollte eine Liste von Städten in einer Dropdown-Liste anzeigen, die doppelte Werte enthält. Lösung: Nach Stadt gruppieren und die erste Stadt für die Liste auswählen.

1 Stimmen

Dies funktionierte in einem Fall, in dem ich mehrere Artikel mit demselben Schlüssel hatte und nur den mit dem jüngsten Aktualisierungsdatum behalten musste. Der Ansatz mit "distinct" würde also nicht funktionieren.

31voto

Hossein Sarshar Punkte 486

Bei mir hat es funktioniert. Verwenden Sie einfach

List<Type> liIDs = liIDs.Distinct().ToList<Type>();

Ersetzen Sie "Typ" durch den gewünschten Typ, z. B. int.

1 Stimmen

Distinct ist in Linq, nicht System.Collections.Generic, wie auf der MSDN-Seite angegeben.

6 Stimmen

Diese Antwort (2012) scheint dieselbe zu sein wie zwei andere Antworten auf dieser Seite, die aus dem Jahr 2008 stammen?

24voto

Keith Punkte 141163

Wie kronoz sagte, können Sie in .Net 3.5 Distinct() .

In .Net 2 konnte man das nachahmen:

public IEnumerable<T> DedupCollection<T> (IEnumerable<T> input) 
{
    var passedValues = new HashSet<T>();

    // Relatively simple dupe check alg used as example
    foreach(T item in input)
        if(passedValues.Add(item)) // True if item is new
            yield return item;
}

Damit kann jede Sammlung abgeleitet werden, und die Werte werden in der ursprünglichen Reihenfolge zurückgegeben.

Normalerweise ist es viel schneller, eine Sammlung zu filtern (da sowohl Distinct() und in diesem Beispiel ist das der Fall), als wenn man Gegenstände daraus entfernen würde.

0 Stimmen

Das Problem bei diesem Ansatz ist jedoch, dass er O(N^2)-mäßig ist, im Gegensatz zu einem Hashset. Aber zumindest ist es offensichtlich, was es tut.

1 Stimmen

@DrJokepu - eigentlich war mir nicht klar, dass die HashSet Konstruktor entkoppelt, was unter den meisten Umständen besser ist. Allerdings würde dadurch die Sortierreihenfolge beibehalten, die ein HashSet nicht.

1 Stimmen

HashSet<T> wurde in 3.5 eingeführt

13voto

Geoff Taylor Punkte 131

Eine Erweiterungsmethode könnte ein guter Weg sein... etwa so:

public static List<T> Deduplicate<T>(this List<T> listToDeduplicate)
{
    return listToDeduplicate.Distinct().ToList();
}

Und dann rufen Sie zum Beispiel so an:

List<int> myFilteredList = unfilteredList.Deduplicate();

12voto

Tom Hawtin - tackline Punkte 142461

In Java (ich nehme an, C# ist mehr oder weniger identisch):

list = new ArrayList<T>(new HashSet<T>(list))

Wenn Sie die ursprüngliche Liste wirklich abändern wollten:

List<T> noDupes = new ArrayList<T>(new HashSet<T>(list));
list.clear();
list.addAll(noDupes);

Um die Reihenfolge beizubehalten, ersetzen Sie einfach HashSet durch LinkedHashSet.

5 Stimmen

In C# wäre es: List<T> noDupes = new List<T>(new HashSet<T>(list)); list.Clear(); list.AddRange(noDupes);

0 Stimmen

In C# ist es auf diese Weise einfacher: var noDupes = new HashSet<T>(list); list.Clear(); list.AddRange(noDupes); :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X