LINQ, де vs


99

Я хочу отримати різницю між тимчасовим і тим, де LINQ методи. Я отримав такі дані від MSDN. Але мені це не було сенсу

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

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

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

Повертає елементи з послідовності, поки задана умова є істинною.

Всі думки вітаються.


1
Хороше запитання - Intellisense в TakeWhile все ще говорить "Повертає елементи ... до тих пір, поки вказана умова є істинною". Це дуже добре можна інтерпретувати як те, що де. Формулювання має бути скоріше на зразок "Повертає елементи ..., поки умова не буде оцінена як хибна".
Пітер

Відповіді:


159

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

30

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

9

Скажіть, у вас є масив, який містить [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].


Я думаю, що поки Тест повернеться лише 1, залежить від відповідей @David B і @Albin Sunnanbo
Мохаммед Табет

Ні, він поверне елементи, поки умова не буде виконана. У цьому випадку 1, 3 і 5 відповідають умові (вони <= 5).
Джим Мішель

8

MSDN каже

Enumerable.TakeWhile Method

Повертає елементи з послідовності, поки задана умова є істинним, а потім пропускає решта елементів.

Enumerable.Where

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

Різниця полягає в тому, що вони Enumerable.TakeWhile пропускають інші елементи з першого невідповідності, відповідають вони умові чи ні


6

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


5

Порядок переданої послідовності абсолютно критичний 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, як a , і озброєний знаннями про те, що перелічувальні коти зростають, дозволить оцінити часткову послідовність:

var result = InfiniteSequence()
    .TakeWhile(n => n < 100)
    .Count();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.