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.

Mohammed Thabet
sumber
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
Albin Sunnanbo
sumber
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
Amy B
sumber
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].

Jim Mischel
sumber
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

naveen
sumber
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

jmoreno
sumber
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();
StuartLC
sumber