LINQ nerede ve takewhile


99

Takewhile ile LINQ yöntemleri arasında bir fark elde etmek istiyorum.Aşağıdaki verileri MSDN'den aldım.Ama bana mantıklı gelmedi

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

Bir koşula göre bir dizi değeri filtreler.

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

Belirtilen koşul doğru olduğu sürece bir dizideki öğeleri döndürür.

Tüm görüşler memnuniyetle karşılanmaktadır.


1
Güzel soru - TakeWhey'deki Intelliense "Belirtilen bir koşul doğru olduğu sürece öğeleri döndürür ..." diyor. Bu, bir Nerede ile aynı şekilde yorumlanabilir. İfade, daha ziyade "Koşul yanlış olarak değerlendirilene kadar öğeleri döndürür ..." gibi bir şey olmalıdır.
Peter

Yanıtlar:


159

TakeWhile koşul yanlış olduğunda dururken, nerede devam eder ve koşulla eşleşen tüm öğeleri bulur

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

Verir

Where
1
2
3
-1
-2
TakeWhile
1
2
3

30

Where eşleşmeleri arayan tüm diziyi inceleyebilir.

Enumerable.Range(1, 10).Where(x => x % 2 == 1)
// 1, 3, 5, 7, 9

TakeWhile ilk maç olmayanla karşılaştığında bakmayı bırakır.

Enumerable.Range(1, 10).TakeWhile(x => x % 2 == 1)
// 1

9

İçeren bir diziniz olduğunu varsayalım [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]. Şimdi:

var whereTest = array.Where(i => i <= 5);dönecek [1, 3, 5, 0, 2, 4].

var whileTest = array.TakeWhile(i => i <= 5);dönecek [1, 3, 5].


Bence whileTest sadece 1 tanesi @David B ve @Albin Sunnanbo cevaplarına bağlıdır
Mohammed Thabet

Hayır, koşul karşılanana kadar ürünleri iade eder. Bu durumda 1, 3 ve 5 koşulu karşılar (bunlar <= 5).
Jim Mischel

8

MSDN diyor

Enumerable.TakeWhile Method

Belirtilen koşul doğru olduğu sürece bir dizideki öğeleri döndürür ve ardından kalan öğeleri atlar.

Enumerable.Where

Bir koşula göre bir dizi değeri filtreler.

Aradaki fark, Enumerable.TakeWhile koşulla eşleşip eşleşmediklerine bakılmaksızın ilk eşleşmeyen öğeden kalan öğeleri atlamasıdır.


6

Mevcut cevaplar doğru olsa da, sonuçların aynı olması durumunda hiçbiri neden TakeWhile kullanmak isteyeceğinizi göstermiyor: Performans. İçinde 2 milyar öğe bulunan bir sıralı listeniz olduğunu ve belirli bir değerden daha az olanları (muhtemelen 10 veya 15 öğe) istediğinizi varsayalım. Where maddesi, 2 milyar ürünün tümünü inceleyecek ve TakeWhile, sağladığınız değere eşit veya daha büyük bir değer bulduğu anda duracaktır.


5

Aktarılan dizinin sırası kesinlikle kritiktir ve TakeWhilebir yüklem geri döner dönmez sona erer false, oysa Wherediziyi ilk falsedeğerin ötesinde değerlendirmeye devam eder .

TakeWhileSıranın sıralaması hakkında ek bilgiye sahip olabileceğiniz büyük, pahalı ve hatta sonsuz numaralandırmaların tembel değerlendirmesi sırasında yaygın olarak kullanılır .

Örneğin, sıra verildiğinde:

IEnumerable<BigInteger> InfiniteSequence()
{
    BigInteger sequence = 0;
    while (true)
    {
        yield return sequence++;
    }
}

A .Where, numaralandırılabilirin bir bölümünü değerlendirmeye çalışan sonsuz bir döngü ile sonuçlanır:

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

Oysa .TakeWhileve numaralandırılanların yükselmekte olduğu bilgisine sahip olan a, kısmi dizinin değerlendirilmesine izin verir:

var result = InfiniteSequence()
    .TakeWhile(n => n < 100)
    .Count();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.