Linq: Seç ve Nerede arasındaki fark nedir?


122

SelectVe Whereyöntemler Linq mevcuttur. Her geliştirici bu iki yöntem hakkında ne bilmeli? Örneğin: biri diğerinin üzerinde ne zaman kullanılmalı, birini diğerinin üzerinde kullanmanın avantajları vb.


7
Bu sorunun CW olarak işaretlenmesi gerektiğini düşünmüyorum, muhtemelen kesin bir cevabı olabilir.
Brandon

1
@Brandon, nesnelse CW'yi işaretlemede yanlış bir şey yoktur.
Rex M

@Rex, katılıyorum. Sadece Seç ve Nerede arasındaki farkın kesin bir cevabı olduğunu ve sorunun ikinci kısmının muhtemelen genel kabul görmüş uygulamalara dayandığını söylemek. Ben sadece OP'nin şeyleri CW olarak işaretleme konusunda emin olmaması durumunda işaret ediyordum. CW olmasını istiyorsa, benim için sorun değil.
Brandon

6
Bunda çok yanlış var. CW işe yaramaz ve insanlar soruları tamamen rastgele CW olarak işaretlediklerinde daha çok oluyor
jalf

Yanıtlar:


126

Nerede

eşleşen öğeleri bulur ve yalnızca eşleşenleri döndürür ( filtreleme ).

-> içeri IEnumerable<A>, IEnumerable<A>dışarı

seçmek

kaynaktaki tüm öğeler için bir şey döndürür ( projeksiyon / dönüşüm ). Bir şey öğelerin kendileri olabilir, ancak daha çok bir tür projeksiyondur.

-> içeri IEnumerable<A>, IEnumerable<B>dışarı


15
Selecther zaman listedeki aynı sayıda öğeyi döndürür (sahip olabileceğiniz filtre koşullarından bağımsız olarak). Wherefiltre durumunuza bağlı olarak daha az öğe döndürebilir.
goku_da_master

Ve işte bir MSDN örneği selectve işte bunlardan biriwhere
Yazarpro

En azından benim için, diğer diller hakkında biraz bilgi sahibi olmak, bunu düşünmek yardımcı oluyor Where == filterveSelect == map
bgusach

52

IEnumerable s üzerinde hareket eden tamamen farklı iki operatör seçin ve nerede .

İlki, Projeksiyon Operatörü dediğimiz , sonuncusu ise Kısıtlama Operatörü .

Bu tür operatörlerin davranışları hakkında bilgi sahibi olmanın ilginç bir yolu, "işlevsel tiplerine" bir göz atmaktır.

  • Seçin: (IEnumerable <T1>, Func <T1, T2>) → IEnumerable <T2> ; girdi olarak hem T1 türündeki IEnumerable öğelerini hem de T1 türündeki öğeleri T2 türündeki öğelere dönüştüren bir işlevi alır. Çıktı, T2 türündeki öğeleri içeren bir IEnumerable'dır.

    Buradan, bu operatörün, girdi işlevini IEnumerable girdisinin her bir öğesine uygulayarak ve sonuçları yeni bir IEnumerable içine sararak kendi çıktısını üreteceği kolayca tahmin edilebilir.

    Matematik benzeri bir gösterim kullanarak, girdi olarak alır (a, b, c, ...): I Sayılabilir <T1> ve f: T1 → T2 ve (f (a), f (b), f (c) üretir , ...): IEnumerable <T2>

  • Nerede: (IEnumerable <T1>, Func <T1, bool>) → IEnumerable <T1> ; bu, T1 türündeki bir IEnumerable öğelerini ve T1 üzerinde bir yüklemi alır (yani, T1 türünde bir girdi için boolean sonuç üreten bir işlev). Çıktının, T1 türündeki öğeleri içeren bir IEnumerable olduğunu da görüyorsunuz.

    Bu sefer, yüklemin öğeye uygulanmasının sonucuna bağlı olarak IEnumerable girdisinin bir elemanının IEnumerable çıktısında mevcut olacağı tahmin edilebilir. Buna operatör adının anlambilimini ekleyerek, girişten yalnızca yüklemin uygulamasında true olarak değerlendirilen öğelerden birini alarak IEnumerable çıktısını üreteceğinden emin olabilirsiniz.

Olan insanlar fonksiyonel programlama arka genellikle böyle düşünüyorum. Bir operatörün ne yaptığını yalnızca türüne bakarak çıkarmanıza (veya en azından tahmin etmenize ...) izin verir!

Bir alıştırma olarak, belgelere bakmadan önce LINQ tarafından IEnumerables üzerinde tanıtılan diğer operatörlere bakmaya ve davranışlarını çıkarmaya çalışın!


47

Farklılar:

Selecttamamen dönüşümle ilgili .

Wheretamamen filtrelemeyle ilgilidir .


18

Select, bir numaralandırmayı yeni bir yapıya eşler. Bir IEnumerable üzerinde bir seçim yaparsanız, aynı sayıda öğeye sahip, ancak belirttiğiniz eşlemeye bağlı olarak farklı türde bir dizi elde edersiniz. IEnumerable'ı filtreler, böylece size orijinal IEnumerable'ın bir alt kümesini verir.



7

Uzantı yöntemlerini nerede ve seçtiklerini nasıl uyguladıklarını biliyorsanız, ne yaptığını tahmin edebilirsiniz ... Nerede uygulamaya çalıştım ve uzantı yöntemlerini seçin ... Buna bir göz atabilirsiniz ...

Nerede Uygulama ::

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

Uygulama seçin ::

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

Uygulamam herhangi bir koleksiyon için iyi çalışıyor ... Ancak Microsoft tarafından uygulanan Uzantı yöntemlerinden farklı, çünkü aynı şeyi uygulamak için ifade ağaçlarını kullanıyorlar.


1

Select it durumunda, yeni bir yapının IEnumerable'ına eşleyebilirsiniz.

  A.Select(x=>new X{UID=x.uid, UNAME=x.uname}) 
  //input as [IEnumerable<A>] -------->  return output as [IEnumerable<X> ]

(), IEnumerable'a bir filtre olarak çalıştığında, sonucu where cümlesine göre döndürecektir.

A.Where(x=>x.uid!=0) //input as [IEnumerable<A>] -------->  return output as [IEnumerable<A> ]
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.