LINQ where vs takewhile

我想得到一个差异之间的 TakeWhileWhere LINQ 方法。我从 MSDN 得到了以下数据。但对我来说毫无意义

Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)

根据谓词筛选值序列。

TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)

只要指定的条件为 true,就返回序列中的元素。

欢迎各种意见。

43796 次浏览

Where 可以检查整个序列以寻找匹配。

Enumerable.Range(1, 10).Where(x => x % 2 == 1)
// 1, 3, 5, 7, 9

当遇到第一个不匹配时,TakeWhile 停止查找。

Enumerable.Range(1, 10).TakeWhile(x => x % 2 == 1)
// 1

当条件为 false 时,TakeWhile 停止,Where继续并找到与条件匹配的所有元素

var intList = new int[] { 1, 2, 3, 4, 5, -1, -2 };
Console.WriteLine("Where");
foreach (var i in intList.Where(x => x <= 3))
Console.WriteLine(i);
Console.WriteLine("TakeWhile");
foreach (var i in intList.TakeWhile(x => x <= 3))
Console.WriteLine(i);

给予

Where
1
2
3
-1
-2
TakeWhile
1
2
3

假设你有一个包含 [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]的数组。现在:

var whereTest = array.Where(i => i <= 5);将返回 [1, 3, 5, 0, 2, 4]

var whileTest = array.TakeWhile(i => i <= 5); will return [1, 3, 5].

MSDN 说

Enumerable.TakeWhile Method

将序列中的元素返回为 只要指定的条件为真, and then skips the remaining elements.

Enumerable.Where

基于。筛选值序列 一个谓词。

区别在于 Enumerable.TakeWhile skips the remaining elements from the first non-match whether they match the condition or not

传递的序列的顺序对于 TakeWhile来说是绝对关键的,一旦谓词返回 falseTakeWhile将立即终止,而 Where将继续计算超过第一个 false值的序列。

TakeWhile的一个常见用法是在对大型、昂贵甚至无限可枚举数进行惰性计算期间,您可能对序列的顺序有更多的了解。

例如:

IEnumerable<BigInteger> InfiniteSequence()
{
BigInteger sequence = 0;
while (true)
{
yield return sequence++;
}
}

.Where将导致一个无限循环,尝试计算可枚举数的一部分:

var result = InfiniteSequence()
.Where(n => n < 100)
.Count();

.TakeWhile,由于知道可枚举数是升序的,将允许对部分序列进行计算:

var result = InfiniteSequence()
.TakeWhile(n => n < 100)
.Count();

虽然现有的答案是正确的,但是没有一个答案指出如果结果相同的话你会使用 TakeWhile: Performance。假设您有一个包含20亿个项目的有序列表,并且您想要那些(可能是10或15个项目)小于给定值的项目。Where 子句将检查所有20亿个项目,而 TakeWhile 将在发现等于或大于您提供的值时立即停止