LINQ where vs takewhile
Я хочу получить разницу между методами takewhile & where LINQ .Я получил следующие данные от MSDN .Но это не имело смысла для меня
Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)
фильтрует последовательность значений на основе предиката.
TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)
возвращает элементы из последовательности, если заданное условие истинно.
все мнения приветствуются.
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
пропускает остальные элементы из первого несоответствия, соответствуют ли они условию или нет
хотя существующие ответы верны, ни один из них не указывает почему Вы хотели бы использовать 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();