LINQ dimana vs takewhile


99

Saya ingin mendapatkan perbedaan antara metode takewhile & where LINQ. Saya mendapatkan data berikut dari MSDN. Tapi itu tidak masuk akal bagi saya

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

Memfilter urutan nilai berdasarkan predikat.

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

Mengembalikan elemen dari urutan selama kondisi yang ditentukan benar.

Semua pendapat disambut baik.


1
Pertanyaan bagus - Intellisense di TakeWhile masih mengatakan "Mengembalikan elemen ... selama kondisi yang ditentukan benar". Ini bisa diartikan sama dengan Dimana. Kata-katanya harus seperti "Mengembalikan elemen ... sampai kondisi dievaluasi sebagai salah".
Peter

Jawaban:


159

TakeWhile berhenti ketika kondisinya salah, Di mana berlanjut dan menemukan semua elemen yang cocok dengan kondisi tersebut

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

Memberi

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

30

Where dapat memeriksa seluruh urutan untuk mencari kecocokan.

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

TakeWhile berhenti melihat ketika bertemu dengan non-pertandingan pertama.

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

9

Katakanlah Anda memiliki array yang berisi [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]. Sekarang:

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

var whileTest = array.TakeWhile(i => i <= 5);akan kembali [1, 3, 5].


Saya pikir whileTest hanya akan mengembalikan 1 tergantung pada @David B dan @Albin Sunnanbo jawaban
Mohammed Thabet

Tidak, itu akan mengembalikan item sampai kondisi tidak terpenuhi. Dalam hal ini, 1, 3, dan 5 memenuhi syarat (yaitu <= 5).
Jim Mischel

8

MSDN mengatakan

Enumerable.TakeWhile Method

Mengembalikan elemen dari urutan selama kondisi yang ditentukan benar, lalu melewatkan elemen yang tersisa.

Enumerable.Where

Memfilter urutan nilai berdasarkan predikat.

Perbedaannya adalah Enumerable.TakeWhile melewatkan elemen yang tersisa dari non-pertandingan pertama apakah mereka cocok dengan kondisi atau tidak


6

Meskipun jawaban yang ada benar, tidak ada yang menunjukkan mengapa Anda ingin menggunakan TakeWhile jika hasilnya sama: Performa. Misalkan Anda memiliki daftar pesanan dengan 2 miliar item di dalamnya, dan Anda menginginkan daftar yang (mungkin 10 atau 15 item) kurang dari nilai tertentu. Klausul Where akan memeriksa semua 2 miliar item, sementara TakeWhile akan berhenti segera setelah menemukan nilai yang sama atau lebih besar dari nilai yang Anda berikan


5

Urutan urutan yang dilewati sangat penting dengan TakeWhile, yang akan berakhir segera setelah predikat kembali false, sedangkan Whereakan terus mengevaluasi urutan di luar nilai pertama false.

Penggunaan umum untuk TakeWhileadalah selama evaluasi malas dari enumerable besar, mahal, atau bahkan tak terbatas di mana Anda mungkin memiliki pengetahuan tambahan tentang pengurutan urutan.

misalnya Diberikan urutannya:

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

A .Whereakan menghasilkan pengulangan tak terbatas yang mencoba mengevaluasi bagian dari enumerable:

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

Sedangkan a .TakeWhile, dan berbekal pengetahuan bahwa enumerables sedang menanjak, akan memungkinkan untuk mengevaluasi urutan parsial:

var result = InfiniteSequence()
    .TakeWhile(n => n < 100)
    .Count();
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.