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?
Antworten
Zu viele Anzeigen?Der einfachste Weg, das Problem zu lösen, besteht darin, die Elemente basierend auf ihrem Wert zu gruppieren und dann einen Vertreter der Gruppe auszuwählen, wenn sich mehr als ein Element in der Gruppe befindet. In LINQ übersetzt sich das wie folgt:
var query = lst.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(y => y.Key)
.ToList();
Wenn Sie wissen möchten, wie oft die Elemente wiederholt werden, können Sie verwenden:
var query = lst.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(y => new { Element = y.Key, Counter = y.Count() })
.ToList();
Dies gibt eine List
eines anonymen Typs zurück, wobei jedes Element die Eigenschaften Element
und Counter
hat, um die benötigten Informationen abzurufen.
Und schließlich, wenn es sich um ein Wörterbuch handelt, das Sie suchen, können Sie verwenden
var query = lst.GroupBy(x => x)
.Where(g => g.Count() > 1)
.ToDictionary(x => x.Key, y => y.Count());
Dies gibt ein Wörterbuch zurück, wobei Ihr Element als Schlüssel und die Anzahl der Wiederholungen als Wert verwendet wird.
Um nur die Duplikatwerte zu finden:
var duplicates = list.GroupBy(x => x.Key).Where(g => g.Count() > 1);
Zum Beispiel:
var list = new[] {1,2,3,1,4,2};
GroupBy
gruppiert die Zahlen nach ihren Schlüsseln und behält die Anzahl (Anzahl der Wiederholungen) bei. Danach überprüfen wir einfach die Werte, die mehr als einmal wiederholt werden.
Um nur die eindeutigen Werte zu finden:
var unique = list.GroupBy(x => x.Key).Where(g => g.Count() == 1);
Zum Beispiel:
var list = new[] {1,2,3,1,4,2};
GroupBy
gruppiert die Zahlen nach ihren Schlüsseln und behält die Anzahl (Anzahl der Wiederholungen) bei. Danach überprüfen wir einfach die Werte, die nur einmal wiederholt wurden, was bedeutet, dass sie eindeutig sind.
Ein weiterer Weg ist die Verwendung von HashSet
:
var hash = new HashSet();
var duplicates = list.Where(i => !hash.Add(i));
Wenn Sie eindeutige Werte in Ihrer Duplikatliste möchten:
var myhash = new HashSet();
var mylist = new List(){1,1,2,2,3,3,3,4,4,4};
var duplicates = mylist.Where(item => !myhash.Add(item)).Distinct().ToList();
Hier ist die gleiche Lösung als generische Erweiterungsmethode:
public static class Extensions
{
public static IEnumerable GetDuplicates(this IEnumerable source, Func selector, IEqualityComparer comparer)
{
var hash = new HashSet(comparer);
return source.Where(item => !hash.Add(selector(item))).ToList();
}
public static IEnumerable GetDuplicates(this IEnumerable source, IEqualityComparer comparer)
{
return source.GetDuplicates(x => x, comparer);
}
public static IEnumerable GetDuplicates(this IEnumerable source, Func selector)
{
return source.GetDuplicates(selector, null);
}
public static IEnumerable GetDuplicates(this IEnumerable source)
{
return source.GetDuplicates(x => x, null);
}
}
Sie können dies tun:
var list = new[] {1,2,3,1,4,2};
var duplicateItems = list.Duplicates();
Mit diesen Erweiterungsmethoden:
public static class Extensions
{
public static IEnumerable Duplicates(this IEnumerable source, Func selector)
{
var grouped = source.GroupBy(selector);
var moreThan1 = grouped.Where(i => i.IsMultiple());
return moreThan1.SelectMany(i => i);
}
public static IEnumerable Duplicates(this IEnumerable source)
{
return source.Duplicates(i => i);
}
public static bool IsMultiple(this IEnumerable source)
{
var enumerator = source.GetEnumerator();
return enumerator.MoveNext() && enumerator.MoveNext();
}
}
Die Verwendung von IsMultiple() in der Duplicates-Methode ist schneller als Count(), da diese nicht die gesamte Sammlung durchläuft.
- See previous answers
- Weitere Antworten anzeigen