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?

1009voto

Factor Mystic Punkte 25189

Wenn Sie .Net 3+ verwenden, können Sie Linq benutzen.

List<T> withDupes = LoadSomeData();
List<T> noDupes = withDupes.Distinct().ToList();

0 Stimmen

Dieser Ansatz kann nur für Listen mit einfachen Werten verwendet werden.

25 Stimmen

Nein, es funktioniert mit Listen, die Objekte beliebigen Typs enthalten. Aber Sie müssen den Standardkomparator für Ihren Typ überschreiben. Etwa so: public override bool Equals(object obj){...}

2 Stimmen

Es ist immer eine gute Idee, ToString() und GetHashCode() in Ihren Klassen zu überschreiben, damit diese Dinge funktionieren.

248voto

Jason Baker Punkte 180981

Vielleicht sollten Sie die Verwendung eines HashSet .

Über den MSDN-Link:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        HashSet<int> evenNumbers = new HashSet<int>();
        HashSet<int> oddNumbers = new HashSet<int>();

        for (int i = 0; i < 5; i++)
        {
            // Populate numbers with just even numbers.
            evenNumbers.Add(i * 2);

            // Populate oddNumbers with just odd numbers.
            oddNumbers.Add((i * 2) + 1);
        }

        Console.Write("evenNumbers contains {0} elements: ", evenNumbers.Count);
        DisplaySet(evenNumbers);

        Console.Write("oddNumbers contains {0} elements: ", oddNumbers.Count);
        DisplaySet(oddNumbers);

        // Create a new HashSet populated with even numbers.
        HashSet<int> numbers = new HashSet<int>(evenNumbers);
        Console.WriteLine("numbers UnionWith oddNumbers...");
        numbers.UnionWith(oddNumbers);

        Console.Write("numbers contains {0} elements: ", numbers.Count);
        DisplaySet(numbers);
    }

    private static void DisplaySet(HashSet<int> set)
    {
        Console.Write("{");
        foreach (int i in set)
        {
            Console.Write(" {0}", i);
        }
        Console.WriteLine(" }");
    }
}

/* This example produces output similar to the following:
 * evenNumbers contains 5 elements: { 0 2 4 6 8 }
 * oddNumbers contains 5 elements: { 1 3 5 7 9 }
 * numbers UnionWith oddNumbers...
 * numbers contains 10 elements: { 0 2 4 6 8 1 3 5 7 9 }
 */

17 Stimmen

Seine unglaubliche Geschwindigkeit... 100.000 Strings mit List brauchen 400s und 8MB ram, meine eigene Lösung braucht 2.5s und 28MB, hashset braucht 0.1s!!! und 11MB ram

3 Stimmen

HashSet keinen Index hat Daher ist es nicht immer möglich, sie zu verwenden. Ich muss einmal eine große Liste ohne Duplikate erstellen und sie dann für ListView im virtuellen Modus. Es war superschnell, eine HashSet<> und wandeln Sie es dann in eine List<> (also ListView kann auf Elemente nach Index zugreifen). List<>.Contains() zu langsam ist.

67 Stimmen

Es wäre hilfreich, wenn es ein Beispiel für die Verwendung eines Hashsets in diesem speziellen Kontext gäbe.

247voto

ljs Punkte 35909

Wie wäre es damit:

var noDupes = list.Distinct().ToList();

In .net 3.5?

0 Stimmen

Wird die Liste dupliziert?

3 Stimmen

@darkgaze dies erstellt einfach eine weitere Liste mit nur eindeutigen Einträgen. So werden alle Duplikate entfernt und es bleibt eine Liste übrig, in der jede Position ein anderes Objekt enthält.

0 Stimmen

Funktioniert dies für eine Liste von Listenelementen, bei denen die Elementcodes doppelt vorhanden sind und die Liste eindeutig sein muss?

99voto

Even Mien Punkte 41507

Initialisieren Sie einfach ein HashSet mit einer Liste desselben Typs:

var noDupes = new HashSet<T>(withDupes);

Oder, wenn Sie eine Liste zurückerhalten möchten:

var noDupsList = new HashSet<T>(withDupes).ToList();

3 Stimmen

... und wenn Sie einen List<T> als Ergebnis verwenden new HashSet<T>(withDupes).ToList()

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.

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