Metode Select
dan Where
tersedia di Linq. Apa yang harus diketahui setiap pengembang tentang kedua metode ini? Misalnya: kapan harus menggunakan salah satu dari yang lain, keuntungan menggunakan salah satu dari yang lain, dll.
Metode Select
dan Where
tersedia di Linq. Apa yang harus diketahui setiap pengembang tentang kedua metode ini? Misalnya: kapan harus menggunakan salah satu dari yang lain, keuntungan menggunakan salah satu dari yang lain, dll.
Jawaban:
Dimana
menemukan item yang cocok dan hanya mengembalikan item yang cocok ( memfilter ).
-> IEnumerable<A>
masuk, IEnumerable<A>
keluar
Pilih
mengembalikan sesuatu untuk semua item dalam sumber ( proyeksi / transformasi ). Sesuatu itu mungkin item itu sendiri, tetapi lebih biasanya merupakan proyeksi dari beberapa jenis.
-> IEnumerable<A>
masuk, IEnumerable<B>
keluar
Select
akan selalu mengembalikan jumlah elemen yang sama dalam daftar (terlepas dari kondisi filter yang mungkin Anda miliki). Where
dapat mengembalikan lebih sedikit elemen tergantung pada kondisi filter Anda.
Where == filter
danSelect == map
Select dan Where adalah dua operator yang sama sekali berbeda yang bekerja pada IEnumerable s.
Yang pertama adalah apa yang kita sebut Operator Proyeksi , sedangkan yang terakhir adalah Operator Pembatasan .
Salah satu cara yang menarik untuk mendapatkan wawasan tentang perilaku operator tersebut adalah dengan melihat "tipe fungsional" mereka.
Pilih: (IEnumerable <T1>, Func <T1, T2>) → IEnumerable <T2> ; dibutuhkan sebagai input baik IEnumerable yang mengandung elemen tipe T1 dan fungsi yang mengubah elemen tipe T1 menjadi elemen tipe T2. Outputnya adalah IEnumerable yang mengandung elemen tipe T2.
Dari sini, orang dapat dengan mudah menebak bahwa operator ini akan menghasilkan outputnya dengan menerapkan fungsi input pada setiap elemen input IEnumerable, dan membungkus hasilnya di dalam IEnumerable baru.
Menggunakan beberapa notasi seperti matematika, dibutuhkan sebagai input (a, b, c, ...): IEnumerable <T1> dan f: T1 → T2 dan menghasilkan (f (a), f (b), f (c) , ...): IEnumerable <T2>
Dimana: (IEnumerable <T1>, Func <T1, bool>) → IEnumerable <T1> ; yang satu ini mengambil IEnumerable yang mengandung elemen tipe T1 dan predikat T1 (yaitu, fungsi yang menghasilkan hasil boolean untuk input tipe T1). Anda melihat bahwa outputnya juga berupa IEnumerable yang mengandung elemen tipe T1.
Kali ini orang akan menebak bahwa elemen input IEnumerable akan hadir pada output IEnumerable tergantung pada hasil penerapan predikat ke elemen tersebut. Menambahkan ke ini semantik nama operator, Anda dapat yakin bahwa itu akan menghasilkan keluaran IEnumerable dengan mengambil dari masukan satu-satunya elemen yang mengevaluasi ke true pada penerapan predikat.
Orang dengan latar belakang pemrograman fungsional biasanya berpikir seperti ini. Ini memungkinkan Anda untuk menyimpulkan (atau setidaknya menebak ...) apa yang dilakukan operator hanya dengan melihat tipenya!
Sebagai latihan, coba lihat operator lain yang diperkenalkan oleh LINQ pada IEnumerables dan simpulkan perilakunya, sebelum melihat dokumentasinya!
Mereka berbeda:
Select
adalah tentang transformasi .
Where
adalah tentang pemfilteran .
Pilih peta yang dapat dihitung ke struktur baru. Jika Anda melakukan pemilihan pada IEnumerable, Anda akan mendapatkan larik dengan jumlah elemen yang sama, tetapi jenis yang berbeda tergantung pada pemetaan yang Anda tentukan. Di mana menyaring IEnumerable sehingga memberikan Anda subset dari IEnumerable asli.
Where
~ = Filter
Select
~ = Peta
Keduanya kembali IEnumerable<T>
Jika Anda tahu bagaimana mereka menerapkan Di mana dan memilih metode ekstensi, Anda dapat memprediksi apa yang dilakukannya ... Saya mencoba menerapkan di mana dan memilih metode ekstensi ... Anda dapat melihatnya ...
Dimana Implementasi ::
public static IEnumerable<Tsource> Where<Tsource> ( this IEnumerable<Tsource> a , Func<Tsource , bool> Method )
{
foreach ( var data in a )
{
//If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)
if ( Method.Invoke ( data ) )
{
yield return data;
}
}
}
Pilih implementasi ::
public static IEnumerable<TResult> Select<TSource , TResult> ( this IEnumerable<TSource> a , Func<TSource , TResult> Method )
{
foreach ( var item in a )
{
//Each iteration call the delegate and return the Data back.(use 'yield' for deferred return)
yield return Method.Invoke ( item );
}
}
Implementasi saya berfungsi dengan baik untuk koleksi apa pun ... Tetapi ini berbeda dari metode Ekstensi yang diimplementasikan Microsoft, Karena mereka menggunakan pohon ekspresi untuk menerapkan hal yang sama.
Dalam kasus Pilih itu Anda dapat memetakan ke IE yang tak terhitung banyaknya dari struktur baru.
A.Select(x=>new X{UID=x.uid, UNAME=x.uname})
//input as [IEnumerable<A>] --------> return output as [IEnumerable<X> ]
Di mana () berfungsi sebagai filter ke IEnumerable, ia akan mengembalikan hasil berdasarkan klausa where.
A.Where(x=>x.uid!=0) //input as [IEnumerable<A>] --------> return output as [IEnumerable<A> ]