2013-07-18 10 views
5

Sicher ist es eine einfache Möglichkeit, eine Sammlung von Werten zu überprüfen hat keine Duplikate [mit dem Standard Comparison von collectionType] in C#/.NETZ ? Muss nicht direkt eingebaut sein, sondern sollte kurz und effizient sein.Wie verifiziere ich eine Sammlung von Werten ist einzigartig (enthält keine Duplikate) in C#

Ich habe viel gesucht, aber ich treffe Beispiele für die Verwendung von collection.Count() == collection.Distinct().Count(), die für mich ineffizient ist. Ich bin nicht an dem Ergebnis interessiert und möchte sofort raus, sobald ich ein Duplikat erkenne, sollte das der Fall sein.

(Ich würde gerne diese Frage und/oder seine Antwort zu löschen, wenn jemand die Duplikate kann darauf hinweisen)

+2

Mit 'Distinct()' ohne einen Vergleich * verwendet * den Standardvergleich des Typs. Es ist nicht klar, was Sie an der Lösung mit 'Distinct()' nicht mögen ... –

+0

@JonSkeet Aktualisiert Q, um mein Problem damit anzuzeigen (ich will nicht das Ergebnis und möchte sofort aufhören). (Es ist eine einfache Wache) –

+1

Richtig, das ist eine ganz andere Frage. –

Antwort

9

okay, wenn Sie nur so schnell erhalten möchten, wie das Duplikat gefunden wird, es ist ganz einfach:

// TODO: add an overload taking an IEqualityComparer<T> 
public bool AllUnique<T>(this IEnumerable<T> source) 
{ 
    if (source == null) 
    { 
     throw new ArgumentNullException("source"); 
    } 
    var distinctItems = new HashSet<T>(); 
    foreach (var item in source) 
    { 
     if (!distinctItems.Add(item)) 
     { 
      return false; 
     } 
    } 
    return true; 
} 

... oder verwenden Sie All, wie Sie bereits gezeigt haben. Ich würde argumentieren, dass dies in diesem Fall etwas einfacher zu verstehen ist ... oder wenn Sie tun möchten All verwenden, würde ich zumindest die Erstellung des Satzes von der Methode Gruppenumwandlung, zur Verdeutlichung:

public static bool IsUnique<T>(this IEnumerable<T> source) 
{ 
    // TODO: validation 
    var distinctItems = new HashSet<T>(); 
    // Add will return false if the element already exists. If 
    // every element is actually added, then they must all be unique. 
    return source.All(distinctItems.Add); 
} 
+0

@RubenBartelink: Ich hatte nicht, als ich anfing, meins zu schreiben, nein. Ich habe auch nicht bemerkt, dass du dich selbst antwortest. –

+0

@RubenBartelink: Ich habe es nicht bemerkt, weil ich beschäftigt war, verwirrt über die Frage selbst zu sein, was das Problem ist. Wie auch immer, ein paar Antworten, die verschiedene Aspekte betonen, schaden nicht. –

+0

Alle meine Kommentare wurden entfernt. Akzeptiert, da die Kommentare in der Erweiterungsmethode wichtig sind und ich sie übernommen habe. –

7

es inline tun, können Sie ersetzen:

collection.Count() == collection.Distinct().Count() 

mit

collection.All(new HashSet<T>().Add); 

(wobei T der Typ der Elemente Ihrer Sammlung ist)

Oder Sie können die oben mit einer Helfer-Extension-Methode [1] extrahieren, so kann man sagen:

collection.IsUnique() 

[1]

static class EnumerableUniquenessExtensions 
{ 
    public static bool IsUnique<T>(this IEnumerable<T> that) 
    { 
     return that.All(new HashSet<T>().Add); 
    } 
} 

(und wie Jon hat in seiner Antwort, man weist darauf hin, wirklich trennen und kommentieren sollten die beiden Linien als solche ‚Niedlichkeit‘ ist in der Regel keine gute Idee)