2011-02-17 64 views
70

我想takewhile &之间的区别在哪里LINQ方法。我从MSDN。但得到了以下数据它没有意义的,我LINQ其中Vs takewhile

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

过滤值基于序列在一个谓词上。

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

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

欢迎您提出意见。

回答

121

当条件为假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 
24

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 
+0

谢谢。现在对我有意义:) – 2011-02-17 17:39:53

6

假设你有一个包含[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]

+0

我认为whileTest将只返回1取决于@David B和@Albin Sunnanbo回答 – 2011-02-17 17:42:22

7

MSDN说

Enumerable.TakeWhile Method

返回序列中的元素作为 只要指定的条件为真, 然后跳过剩余的元素。

Enumerable.Where

筛基于 谓词值的序列。

的区别在于Enumerable.TakeWhile跳过从第一非匹配剩余元素它们是否匹配的条件或不

4

通过该序列的顺序与TakeWhile绝对关键的,这将终止为只要谓词返回false,而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(); 
5

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