32

C# では、次のようなものを使用できます。

List<string> myList = new List<string>();

if (myList.Count != myList.Distinct().Count())
{
    // there are duplicates
}

リスト内の重複要素をチェックします。ただし、nullリストにアイテムがある場合、これは誤検出を引き起こします。いくつかの遅いコードを使用してこれを行うことができますが、簡潔な方法で null 値を無視しながら、リスト内の重複をチェックする方法はありますか?

4

5 に答える 5

56

パフォーマンスが心配な場合は、次のコードは最初の重複アイテムが見つかるとすぐに停止します。これまでの他のすべてのソリューションでは、入力全体を少なくとも 1 回反復する必要があります。

var hashset = new HashSet<string>();
if (myList.Where(s => s != null).Any(s => !hashset.Add(s)))
{
    // there are duplicates
}

hashset.Addfalseアイテムがセットに既に存在する場合は戻り、最初の値が発生するとすぐに戻りますAny。したがって、これは最初の重複までの入力のみを検索します。truetrue

于 2013-06-06T11:43:40.910 に答える
32

私はこれを別の方法で行います:

Linq ステートメントが遅延評価されると、.Anyショートサーキットになります。つまり、重複がある場合、リスト全体を反復してカウントする必要はありません。したがって、より効率的になります。

var dupes = myList
    .Where(item => item != null)
    .GroupBy(item => item)
    .Any(g => g.Count() > 1);

if(dupes)
{
    //there are duplicates
}

編集: http://pastebin.com/b9reVaJu _ _ _ GroupBy_Count()

編集 2:以下のローリングの回答は、このアプローチよりも少なくとも 5 倍速いようです!

于 2013-06-06T11:08:13.923 に答える
11
var nonNulls = myList.Where(x => x != null)
if (nonNulls.Count() != nonNulls.Distinct().Count())
{
    // there are duplicates
}
于 2013-06-06T11:06:13.427 に答える
4

2 つの null は重複していますね。

とにかく、null なしでリストを比較します。

var denullified = myList.Where(l => l != null);
if(denullified.Count() != denullified.Distinct().Count()) ...
于 2013-06-06T11:06:41.003 に答える
1

延期されていないため、私の最初の試みは最悪です。

代わりは、

var duplicates = myList
    .Where(item => item != null)
    .GroupBy(item => item)
    .Any(g => g.Skip(1).Any());

悪い実装が削除されました。

于 2013-06-06T11:16:26.493 に答える