LINQ, где vs takewhile

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

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

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

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

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

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

Ответ 1

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

Ответ 2

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

Ответ 3

MSDN говорит

Enumerable.TakeWhile Method

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

Enumerable.Where

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

В то время как a .TakeWhile и вооруженный знанием о том, что перечислимые объекты являются восходящими, позволит оценить частичную последовательность:

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