バイトの小さなリストがあり、それらがすべて異なる値であることをテストしたいと思います。たとえば、私はこれを持っています:
List<byte> theList = new List<byte> { 1,4,3,6,1 };
すべての値が異なるかどうかを確認するための最良の方法は何ですか?
回答:
Enumerable.Distinct+よりも効率的な別のアプローチがありますEnumerable.Count(シーケンスがコレクションタイプでない場合はなおさらです)。これは、使用してHashSet<T>重複を排除するには、検索に非常に有効であるとカウントプロパティがあります。
var distinctBytes = new HashSet<byte>(theList);
bool allDifferent = distinctBytes.Count == theList.Count;
または別の-より微妙で効率的な-アプローチ:
var diffChecker = new HashSet<byte>();
bool allDifferent = theList.All(diffChecker.Add);
HashSet<T>.Addfalse要素がすでにHashSet。にあるために追加できなかった場合に戻ります。 Enumerable.All最初の「false」で停止します。
Assert.IsTrue(samples.Add(AwesomeClass.GetUnique()));。彼らは今もそうです:)あなたのために+1ティム:)
bool allDifferent = theList.All(s => diffChecker.Add(s))
List.All(HashSet.Add))は、ほとんどすべての場合、他の2つよりもはるかに高速であるようです
さて、これが私が標準の.Netを使用して考えることができる最も効率的な方法です
using System;
using System.Collections.Generic;
public static class Extension
{
public static bool HasDuplicate<T>(
this IEnumerable<T> source,
out T firstDuplicate)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
var checkBuffer = new HashSet<T>();
foreach (var t in source)
{
if (checkBuffer.Add(t))
{
continue;
}
firstDuplicate = t;
return true;
}
firstDuplicate = default(T);
return false;
}
}
基本的に、最初の重複を見つけるだけの場合、シーケンス全体を2回列挙することのポイントは何ですか。
空の単一要素シーケンスを特別にケーシングすることでこれをさらに最適化できますが、最小限のゲインで読みやすさ/保守性が低下します。
sequenceはずですsource)。しかし、これらが修正されるとうまく機能します
if (!checkBuffer.Add(t)) { firstDuplicate = t; return true }ループにあるべきだと思います。
同様のロジックDistinct使用GroupBy:
var isUnique = theList.GroupBy(i => i).Count() == theList.Count;
theList.GroupBy(o => o.SomeProperty).Count() == theList.Count;、Distinct()で許可されていないときに、プロパティに関する一意性を確認する場合に役立ちます。
多くの解決策があります。
そして、間違いなく、「juergend」や「TimSchmelter」としてLINQを使用したより美しいものが言及されています。
しかし、「複雑さ」とスピードをむき出しにする場合、最善の解決策はそれを自分で実装することです。解決策の1つは、Nサイズの配列を作成することです(バイトの場合は256です)。そして、配列をループします。すべての反復で、値が1の場合、一致する番号インデックスをテストします。つまり、すでに配列インデックスをインクリメントしているため、配列が区別されません。それ以外の場合は、配列セルをインクリメントしてチェックを続行します。 。
重複する値を見つけたい場合は、別の解決策。
var values = new [] { 9, 7, 2, 6, 7, 3, 8, 2 };
var sorted = values.ToList();
sorted.Sort();
for (var index = 1; index < sorted.Count; index++)
{
var previous = sorted[index - 1];
var current = sorted[index];
if (current == previous)
Console.WriteLine(string.Format("duplicated value: {0}", current));
}
出力:
duplicated value: 2
duplicated value: 7