在C# List中查找值的最有效方法

19
在C#中,如果我有一个类型为bool的列表。最快的方法是确定列表是否包含true值?我不需要知道有多少个或者true值在哪里。我只需要知道是否存在一个true值。我将搜索许多非常大的列表。

有点取决于您如何填充该列表。List<bool>.Any() 可以得到您想要的结果,但它仍然是最坏情况下的 O(N)。 - IdeaHat
(它实际上是那个的副本。) - Jon Skeet
如果你将会搜索的次数比存储这些值的次数多,并且速度非常关键,你可以为每个列表单独存储它是否具有真实值。 - Twon-ha
非常大是多大? 4,000,000,000个以上的项目吗? - tia
8个回答

24

只需使用bool trueInList = list.Contains(true); 。这将循环遍历列表,直到存在true为止。

为什么需要在如此简单的用例中使用更快的东西?


9
如果你已经有了List,为什么要使用Linq呢?+1 - Sergey Berezovskiy
1
(恢复评论)我会使用这种简单的方法,但是我想指出手写循环的速度比它快3倍以上-请参见下面的答案。 - Matthew Watson
@MatthewWatson:您的回答似乎已被删除。 - Tim Schmelter

12

使用list.Contains(true)或list.Any(true)。对于普通的列表,两者的复杂度都是O(n)。由于Any()是一个扩展方法,需要调用委托,所以Contains()可能会稍微快一些。但为了确保,我建议使用大型集合测试这两个方法。


谢谢Treze。根据你的说法,我会尝试两种方法并看哪个更快。 - Aaron Benzel
@AaronBenzel 你也可以尝试一下我在答案中提到的循环方法,看看对你来说是否更快。在某些系统上似乎是这样的。 - Matthew Watson
就像你说的那样,相关的Any重载需要一个委托。你说list.Any(true),但是true不是一个委托,所以无法编译通过。如果你想使用LINQ(出于某种疯狂的原因),它的方法也叫做Contains。要调用LINQ的Contains,可以使用list.AsEnumerable().Contains(true)(其中AsEnumerable确保List<>本身的实例方法不适用),或者使用list.Contains<bool>(true)(其中泛型参数的存在排除了List<>的非泛型实例方法)。但正如lazyberezovsky在其他地方所说:如果你有List<>,为什么要使用LINQ呢? - Jeppe Stig Nielsen
@JeppeStigNielsen,你当然是对的,关于签名。我也看不出使用LINQ的理由,只是想说明我看到的两种可能性。 - treze

6
你可以使用 Any() 函数。
list.Any(b => b);

由于委托调用,这肯定不是最快的选项。 - usr

3

试试这个:

var result = myBoolList.Any(i => i==true);

如果它是可空的,我会考虑 ==true,为什么现在要添加它呢? - Silvermind
等等,LINQ有一个特殊的方法用于模式.Any(x => x==WANTED),它被称为.Contains(WANTED)。(这假设编译时重载的==具有与___virtual___ object.Equals(object)方法相同的行为,但在这种情况下是成立的。) - Jeppe Stig Nielsen

1
您使用Any(...)
list.Any(c => c == true);

或者只是
list.Any(c => c);

1
您可以使用列表的BinarySearch方法。
if(list.BinarySearch(true) > 0){...}

1
不,你不能。为什么列表会被排序呢? - Matthew Watson
1
即使列表已经排好序了(这对于 List<bool> 来说可能有些奇怪),仍然不能说使用 >0 是正确的。应该是 >=0 才行。因为列表可能非常短,只有 true 条目,那么 BinarySearch 可能会返回 0,表示:在索引 0 处找到了匹配项,所以 list[0] 匹配。 - Jeppe Stig Nielsen

1
这个答案提供了一个不同的角度:为什么要将布尔值存储在列表中?将它们存储为两个整数:int falseCount; int trueCount;
包含测试就像这样简单:trueCount > 0 假设您需要该列表,请使用List.Contains,因为它直接搜索底层数组。
甚至可以使用反射提取底层数组,并在硬编码比较循环中搜索它。您可以在那里使用文字true来比较每个元素。您甚至可以展开循环或进行不安全的代码技巧。

0
bool val = false;
Foreach(bool val in listofvalue)
{
   val |= val;
}

if(val)
print "List contain true value"

else

print "List contain false value"

2
不需要遍历所有的值来判断它们中是否有一个为真。 - treze
它被称为 |= 而不是 =||。但是 @treze 是正确的,没有必要将它们全部 OR 在一起。 - Jeppe Stig Nielsen
抱歉朋友们............:( - Jitendra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接