2013-07-18 6 views
5

Z pewnością istnieje prosty sposób sprawdzenia, czy zbiór wartości nie ma duplikatów [przy użyciu domyślnego Comparison z collection 's Type] w języku C#/.NET? Nie musi być bezpośrednio wbudowany, ale powinien być krótki i wydajny.Jak sprawdzić, czy zbiór wartości jest unikalny (nie zawiera żadnych duplikatów) w języku C#

Szukałem dużo ale zachować uderzanie przykłady użycia collection.Count() == collection.Distinct().Count() co dla mnie jest nieefektywne. Nie jestem zainteresowany wynikiem i chce wyskoczyć jak najszybciej wykryć duplikat, że powinno być inaczej.

(chciałbym, aby usunąć to pytanie i/lub jego odpowiedź, jeśli ktoś może wskazać duplikaty)

+2

Korzystanie 'Wyraźny()' bez comparer * nie * użyć porównania domyślnego typu. Nie jest jasne, co Ci się nie podoba w rozwiązaniu, używając 'Distinct()' ... –

+0

@ JonSkeet Zaktualizowano Q, aby wskazać mój problem z tym (nie chcę wyniku i chcę od razu odejść). (Jego prosta osłona) –

+1

Prawda, że ​​to zupełnie inna kwestia. –

Odpowiedz

9

porządku, jeśli chcesz po prostu wyjść, gdy tylko zostanie znaleziony duplikat, to proste:

// 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; 
} 

... lub użyj All, jak już pokazano. Twierdzę, że jest to nieco łatwiejsze do zrozumienia w tym przypadku ... lub jeśli chcesz użyć All, to przynajmniej oddzielę tworzenie zestawu od konwersji grupy metodowej, dla jasności:

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: Nie miałem, kiedy zacząłem pisać moje, nie. Nie zauważyłem też, że masz zamiar odpowiedzieć sobie samemu. –

+0

@RubenBartelink: Nie zauważyłem tego, ponieważ byłem zajęty myleniem samego pytania, co stanowi problem. W każdym razie posiadanie kilku odpowiedzi podkreślających różne aspekty nie szkodzi. –

+0

Usunięto wszystkie moje komentarze, aby uporządkować. Zaakceptowane jako komentarze w metodzie rozszerzenia są ważne i wziąłem je. –

7

robi to inline, można wymienić:

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

z

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

(gdzie T to rodzaj elementów kolekcji)

Albo można wyodrębnić powyższego sposobu rozszerzenia pomocnika [1], więc można powiedzieć:

collection.IsUnique() 

[1]

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

(i jak Jon podkreślił w swojej odpowiedzi, naprawdę należy oddzielić i skomentować dwie linie w takim charakterze „bystrość” jest ogólnie nie jest dobrym pomysłem)

Powiązane problemy