LINQ哪里vs随身带


99

我想知道Takewhile和LINQ方法之间的区别。我从MSDN获得了以下数据。但是对我来说这没有意义

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

根据谓词过滤值序列。

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

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

欢迎所有意见。


1
很好的问题-TakeWhile上的Intellisense仍然说“只要指定条件为真,就会返回元素”。这很可能解释为与Where相同。措词应该类似于“返回元素...,直到条件评估为假”。
彼得

Answers:


159

当条件为假时,TakeWhile停止;在条件继续的地方继续查找所有与条件匹配的元素

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

30

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

9

假设您有一个包含的数组[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);会回来的[1, 3, 5]


我认为whileTest将仅返回1个依赖于@David B和@Albin Sunnanbo的答案
Mohammed Thabet

不,它将返回项目直到不满足条件。在这种情况下,1、3和5满足条件(它们<= 5)。
Jim Mischel

8

MSDN说

Enumerable.TakeWhile Method

只要指定条件为true,就从序列中返回元素,然后跳过其余元素。

Enumerable.Where

根据谓词过滤值序列。

区别在于,无论是否符合条件,都会从第一个不匹配项Enumerable.TakeWhile 跳过其余的元素


6

尽管现有的答案是正确的,但它们都没有指出为什么结果相同的情况下为什么要使用TakeWhile:性能。假设您有一个包含20亿件商品的有序列表,并且您想要的数量(可能是10或15件)少于给定的数量。Where子句将检查所有20亿个项目,而TakeWhile会在发现等于或大于您提供的值的值时立即停止


5

传递的序列的顺序对于绝对至关重要TakeWhile,它将在谓词返回后立即终止false,而Where将继续评估超出第一个false值的序列。

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

例如给定顺序:

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

A .Where将导致一个无限循环,试图评估可枚举的一部分:

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

鉴于.TakeWhile,并且知道枚举数正在上升,因此可以评估部分序列:

var result = InfiniteSequence()
    .TakeWhile(n => n < 100)
    .Count();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.