LINQ where vs takewhile


Я хочу получить разницу между методами takewhile & where LINQ .Я получил следующие данные от MSDN .Но это не имело смысла для меня

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

фильтрует последовательность значений на основе предиката.

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

возвращает элементы из последовательности, если заданное условие истинно.

все мнения приветствуются.

6 80

6 ответов:

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

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

скажем, у вас есть массив, который содержит [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].

MSDN говорит

Enumerable.TakeWhile Method

возвращает элементы последовательности, как пока указанное условие истинно, а затем пропускает остальные элементы.

Enumerable.Where

фильтрует последовательность значений на основе предикат.

разница в том, что Enumerable.TakeWhileпропускает остальные элементы из первого несоответствия, соответствуют ли они условию или нет

хотя существующие ответы верны, ни один из них не указывает почему Вы хотели бы использовать TakeWhile, если результаты будут одинаковыми: производительность. Предположим, у вас есть упорядоченный список с 2 миллиардами элементов в нем, и вы хотите, чтобы те, которые (вероятно, 10 или 15 элементов) меньше, чем заданный vallue. В предложении Where будут рассмотрены все 2 миллиарда элементов, а TakeWhile остановится, как только он найдет значение, равное или большее вашего предоставленного значения

порядок прохождения последовательности абсолютно критичен с 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();