List<bool>
多数の値。リスト内のすべてのアイテムがfalse
と等しいかどうかを確認する最も効率的な方法は何ですか?
ここでは言及していませんが、非常に高速なソリューションはContains
を使用することです
if (!myList.Contains(true))
// Great success - all values false!
Contains
とIEnumerable.Any
を比較し、Contains
の戻りが速くなりました。私のテストでは、IEnumerable.All
はIEnumerable.Any
と同じように実行されましたが、おそらくこれらの両方の機能に内部で同様のアルゴリズムが使用されています。 IEnumerable.Exists
とIEnumerable.Any
よりもパフォーマンスが優れていたIEnumerable.All
もチェックしましたが、Contains
よりも低速でした。
10,000,000のboolエントリのリスト(同様の結果で0と1のエントリも試しました)で、次のメトリックを思いつきました。
Any=95msで経過
すべて経由の経過= 88ms
Exists by Exists = 27ms
を介して経過(含む)=17ms
〜は〜5.59倍高速ですthan any!
次のコードでテスト済み:
// setup initial vars
var myList = new List<bool>();
for (int x = 0; x < 10000000; x++)
myList.Add(false);
var containsAllFalse = false;
Stopwatch sw = new Stopwatch();
// start test
sw.Start();
containsAllFalse = !myList.Any(x => x);
sw.Stop();
// get result for Any
var timeAny = sw.ElapsedMilliseconds;
// reset variable state (just in case it affects anything)
containsAllFalse = false;
// start test 2
sw.Restart();
containsAllFalse = myList.All(x => x == false);
sw.Stop();
// get result for All
var timeAll = sw.ElapsedMilliseconds;
// reset variable state (just in case it affects anything)
containsAllFalse = false;
// start test 3
sw.Restart();
containsAllFalse = !myList.Exists(x => x == true);
sw.Stop();
// get result for All
var timeExists = sw.ElapsedMilliseconds;
// reset variable state (just in case it affects anything)
containsAllFalse = false;
// start test 4
sw.Restart();
containsAllFalse = !myList.Contains(true);
sw.Stop();
// get result from Contains
var timeContains = sw.ElapsedMilliseconds;
// print results
var percentFaster = Math.Round((double)timeAny / timeContains, 2);
Console.WriteLine("Elapsed via Any = {0}ms", timeAny);
Console.WriteLine("Elapsed via All = {0}ms", timeAll);
Console.WriteLine("Elapsed via Exists = {0}ms", timeExists);
Console.WriteLine("Elapsed via Contains = {0}ms", timeContains);
Console.WriteLine("Contains is ~{0}x faster than Any!", percentFaster);
これは、タイプが2つの状態しか持てないタイプでのみ機能することに注意してください(つまり、Nullable<bool>
などの> 2状態の変数は機能しません)
Enumerable.Any
最初の一致で条件を満たしていることがわかります。 Habibが、AnyをEnumerable.Allとして使用する方が適切であると言ったように、boolの空のリストに対してはtrueを返します。
!lst.Any(c=> c == true);
または Enumerable.All を使用します
lst.All(c=> c == false);
IEnumerable.Any / All の使用に同意します。ただし、現在最も投票されている回答(これを書いている時点では間違っていました)と、Any vs Allの関連するコメントのいくつかに同意しません。
これらの次の操作は、意味的にと同等です。否定はbothの内側、述語、および演算結果に適用されることに注意してください。
_!l.Any(x => f(x))
l.All(x => !f(x))
_
さて、この場合、私たちはこうして探しています:
それがnotの場合、anyの真の値がある場合。
_!l.Any(x => x) // f(x) = x == true
_
または、
every値がnottrueである場合です。
_l.All(x => !x) // f'(x) = !f(x) = !(x == true)
_
空のリストに特別なものはありません。結果は同じです。 !empty.Any(..)
はempty.All(..)
と同様にfalseであり、上記の同値関係は引き続き有効です。
さらに、bothフォームは遅延評価され、 LINQ To Objects ;で同数の評価が必要です。内部的には、シーケンス実装の違いは、単に述語と結果値のチェックを無効にしているだけです。
LINQ's
All
メソッドを使用できます。
list.All(x => x == false);
false
に等しい値が見つかった場合、すぐにtrue
を返します。