2009-07-15 17 views
4

誰でも項目の順序が任意の重複を持っている場合は見つけるための良いと効率的な拡張メソッドを持っていますか?のC#:IEnumerableをの良いと効率的な実装<T> .HasDuplicates

は、私は拡張メソッドにreturn subjects.Distinct().Count() == subjects.Count()を置くことができると思いますが、種類のより良い方法があるはずと感じています。この方法では、要素を2回カウントし、すべてのdistict要素を並べ替える必要があります。より良い実装では、見つかった最初の複製でtrueを返す必要があります。良い提案はありますか?私は最も簡単な拡張メソッドがあると思い

答えて

13
public static bool HasDuplicates<T>(this IEnumerable<T> subjects) 
{ 
    return HasDuplicates(subjects, EqualityComparer<T>.Default); 
} 

public static bool HasDuplicates<T>(this IEnumerable<T> subjects, IEqualityComparer<T> comparer) 
{ 
    HashSet<T> set = new HashSet<T>(comparer); 
    foreach (T item in subjects) 
    { 
     if (!set.Add(item)) 
      return true; 
    } 

    return false; 
} 
+0

ここで*かなり*賢明です...その1つを試してみる必要があります! – Svish

+1

これは便利かもしれません...私はHashSetがコンパクトなフレームワークでサポートされているとは思わない... grrrrr。 –

+0

あなたは 'Dictionary < T、K >'と同じことをすることができますが、メモリの効率はやや劣ります。 'Dictionary < T、K > .Add'は' bool'を返しませんが、 'Count'プロパティはコードの数行を犠牲にして調べるのが非常に速いでしょう。 –

1

...

public static bool HasDuplicates<T>(this IEnumerable<T> subjects) 
{ 
    return subjects.HasDuplicates(EqualityComparer<T>.Default); 
} 

public static bool HasDuplicates<T>(this IEnumerable<T> subjects, IEqualityComparer<T> comparer) 
{ 
    ... 
} 

でもないことのスマートな実装が可能だろうかかなり確実:

私は輪郭がこのようなものかもしれないと想像します以下。

public static bool HasDuplicates<T>(this IEnumerable<T> enumerable) { 
    var hs = new HashSet<T>(); 
    foreach (var cur in enumerable) { 
    if (!hs.Add(cur)) { 
     return false; 
    } 
    } 
} 
+0

return文が欠けていると思っています。とにかく、他の答えに非常によく似ていて、十分な担当者がいるので、他の回答を受け入れました; p – Svish

4

これは生産コードです。素晴らしい作品:

public static bool HasDuplicates<T>(this IEnumerable<T> sequence) { 
    var set = new HashSet<T>(); 
    return !sequence.All(item => set.Add(item)); 
} 
+0

かなり短いものを除いて、私の受け入れられた答えとほとんど同じです。面白い:) – Svish

+0

はい、最初の答えと同じアプローチ(280Z28から);そうでなければ示唆することを意味しなかった。 –

関連する問題