546 Stimmen

C# LINQ Duplikate in Liste finden

Wie kann ich unter Verwendung von LINQ aus einer List eine Liste abrufen, die Einträge enthält, die mehr als einmal wiederholt werden, sowie ihre Werte?

6voto

Ricardo Figueiredo Punkte 1346

Ich habe eine Erweiterung erstellt, um darauf zu antworten. Du könntest sie in deinen Projekten verwenden, ich denke, dass sie in den meisten Fällen zurückgibt, wenn du nach Duplikaten in einer Liste oder Linq suchst.

Beispiel:

//Dummy-Klasse zum Vergleichen in der Liste
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public Person(int id, string name, string surname)
    {
        this.Id = id;
        this.Name = name;
        this.Surname = surname;
    }
}

//Die statische Erweiterungsklasse
public static class Extention
{
    public static IEnumerable getMoreThanOnceRepeated(this IEnumerable extList, Func groupProps) where T : class
    { //Gibt nur die zweite und alle weiteren Wiederholungen zurück
        return extList
            .GroupBy(groupProps)
            .SelectMany(z => z.Skip(1)); //Überspringt das erste Vorkommen und gibt alle weiteren zurück, die wiederholen
    }
    public static IEnumerable getAllRepeated(this IEnumerable extList, Func groupProps) where T : class
    {
        //Alle Zeilen abrufen, die wiederholen
        return extList
            .GroupBy(groupProps)
            .Where(z => z.Count() > 1) //Nur die unterschiedlichen filtern
            .SelectMany(z => z);//Alles in "where" muss zurückgegeben werden
    }
}

//wie man es benutzt:
void DuplicateExample()
{
    //Liste bevölkern
    List PersonsLst = new List(){
    new Person(1,"Ricardo","Figueiredo"), //erstes Duplikat zum Beispiel
    new Person(2,"Ana","Figueiredo"),
    new Person(3,"Ricardo","Figueiredo"),//zweites Duplikat zum Beispiel
    new Person(4,"Margarida","Figueiredo"),
    new Person(5,"Ricardo","Figueiredo")//drittes Duplikat zum Beispiel
    };

    Console.WriteLine("Alle:");
    PersonsLst.ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
    /* AUSGABE:
        Alle:
        1 -> Ricardo Figueiredo
        2 -> Ana Figueiredo
        3 -> Ricardo Figueiredo
        4 -> Margarida Figueiredo
        5 -> Ricardo Figueiredo
        */

    Console.WriteLine("Alle Zeilen mit wiederholten Daten");
    PersonsLst.getAllRepeated(z => new { z.Name, z.Surname })
        .ToList()
        .ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
    /* AUSGABE:
        Alle Zeilen mit wiederholten Daten
        1 -> Ricardo Figueiredo
        3 -> Ricardo Figueiredo
        5 -> Ricardo Figueiredo
        */
    Console.WriteLine("Nur mehrfach wiederholt");
    PersonsLst.getMoreThanOnceRepeated(z => new { z.Name, z.Surname })
        .ToList()
        .ForEach(z => Console.WriteLine("{0} -> {1} {2}", z.Id, z.Name, z.Surname));
    /* AUSGABE:
        Nur mehrfach wiederholt
        3 -> Ricardo Figueiredo
        5 -> Ricardo Figueiredo
        */
}

3voto

Es gibt eine Antwort, aber ich habe nicht verstanden, warum es nicht funktioniert;

var anyDuplicate = enumerable.GroupBy(x => x.Key).Any(g => g.Count() > 1);

Meine Lösung sieht in dieser Situation so aus;

var duplicates = model.list
                    .GroupBy(s => s.SAME_ID)
                    .Where(g => g.Count() > 1).Count() > 0;
if(duplicates) {
    doSomething();
}

3voto

fthtnrvr Punkte 21

Nur ein anderer Ansatz:

Für nur HasDuplicate:

bool hasAnyDuplicate = list.Count > list.Distinct().Count;

Für doppelte Werte

List duplicates = new List();
duplicates.AddRange(list);
list.Distinct().ToList().ForEach(x => duplicates.Remove(x));

// für eindeutige doppelte Werte:
duplicates.Distinct():

1voto

GeoB Punkte 55

Komplettes Set von Linq-to-SQL-Erweiterungen der Duplikatsfunktionen, die in MS SQL Server überprüft wurden. Ohne die Verwendung von .ToList() oder IEnumerable. Diese Abfragen werden im SQL Server ausgeführt anstatt im Speicher. Die Ergebnisse werden nur im Speicher zurückgegeben.

public static class Linq2SqlExtensions {

    public class CountOfT {
        public T Key { get; set; }
        public int Count { get; set; }
    }

    public static IQueryable Duplicates(this IQueryable source, Expression> groupBy)
        => source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(s => s.Key);

    public static IQueryable GetDuplicates(this IQueryable source, Expression> groupBy)
        => source.GroupBy(groupBy).Where(w => w.Count() > 1).SelectMany(s => s);

    public static IQueryable> DuplicatesCounts(this IQueryable source, Expression> groupBy)
        => source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(y => new CountOfT { Key = y.Key, Count = y.Count() });

    public static IQueryable> DuplicatesCountsAsTuble(this IQueryable source, Expression> groupBy)
        => source.GroupBy(groupBy).Where(w => w.Count() > 1).Select(s => Tuple.Create(s.Key, s.Count()));
}

1voto

user1785960 Punkte 512

Linq-Anfrage:

var query = from s2 in (from s in someList group s by new { s.Column1, s.Column2 } into sg select sg) where s2.Count() > 1 select s2;

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