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();