Linq: Select और Where में क्या अंतर है


122

Selectऔर Whereतरीकों Linq में उपलब्ध हैं। हर डेवलपर को इन दो तरीकों के बारे में क्या पता होना चाहिए? उदाहरण के लिए: जब एक के ऊपर एक का उपयोग करना है, तो दूसरे के ऊपर एक का उपयोग करने के किसी भी फायदे, आदि।


7
मुझे नहीं लगता कि इस प्रश्न को सीडब्ल्यू के रूप में चिह्नित किया जाना चाहिए, इसका संभवतः एक निश्चित उत्तर हो सकता है।
ब्रैंडन

1
@ अगर यह उद्देश्य है तो सीडब्ल्यू को चिह्नित करने में कुछ भी गलत नहीं है।
रेक्स एम।

@Rex, मैं सहमत हूँ। बस यह कहना कि चयन और कहां के बीच अंतर का एक निश्चित उत्तर है, और सवाल का दूसरा भाग आमतौर पर स्वीकृत प्रथाओं से आधारित होगा। मैं सिर्फ यह इंगित कर रहा था कि ओपी सीडब्ल्यू के रूप में चीजों को चिह्नित करने के बारे में अनिश्चित था। अगर उसने सीडब्ल्यू होने का इरादा किया, तो मेरे द्वारा ठीक ठाक है।
ब्रैंडन

6
इसमें बहुत गलत है। सीडब्ल्यू बेकार है, और अधिक हो रही है, जब लोग सीडब्ल्यू के रूप में पूरी तरह से यादृच्छिक पर प्रश्नों को चिह्नित करते हैं
जुलफ

जवाबों:


126

कहाँ पे

उन आइटमों को खोजता है जो मेल खाते हैं और केवल वही करते हैं जो ( फ़िल्टरिंग ) करते हैं।

-> IEnumerable<A>अंदर, IEnumerable<A>बाहर

चुनते हैं

स्रोत ( प्रक्षेपण / परिवर्तन ) में सभी वस्तुओं के लिए कुछ देता है । यह कुछ चीजें स्वयं हो सकती हैं, लेकिन आमतौर पर किसी प्रकार का एक प्रक्षेपण हैं।

-> IEnumerable<A>अंदर, IEnumerable<B>बाहर


15
Selectसूची में तत्वों की एक ही संख्या हमेशा वापस आ जाएगी (भले ही आपके पास एक फ़िल्टर स्थिति हो)। Whereआपके फ़िल्टर की स्थिति के आधार पर कम तत्व वापस कर सकते हैं।
गोकू_डा_मास्टर

और यहाँ एक MSDN उदाहरण है selectऔर यहाँ एक के लिए हैwhere
yazanpro

कम से कम मेरे लिए, अन्य भाषाओं के साथ कुछ पृष्ठभूमि होने पर, यह सोचने में मदद मिलती है कि Where == filterऔरSelect == map
9

52

चयन करें और कहां दो पूरी तरह से अलग ऑपरेटरों IEnumerable एस पर अभिनय कर रहे हैं ।

पहला वह है जिसे हम प्रोजेक्शन ऑपरेटर कहते हैं , जबकि अंतिम एक प्रतिबंध ऑपरेटर है

ऐसे ऑपरेटरों के व्यवहार पर अंतर्दृष्टि रखने का एक दिलचस्प तरीका उनके "कार्यात्मक प्रकार" पर एक नज़र रखना है।

  • चयन करें: (IEnumerable <T1>, Func <T1, T2>) → IEnumerable <T2> ; यह टाइप 1 के IEnumerable दोनों तत्वों के इनपुट के रूप में लेता है और प्रकार T1 के तत्वों में टाइप T1 के तत्वों को बदलने वाला फ़ंक्शन होता है। आउटपुट एक IEnumerable है जिसमें टाइप T2 के तत्व हैं।

    इससे, कोई भी आसानी से अनुमान लगा सकता है कि यह ऑपरेटर इनपुट IEnumerable के प्रत्येक तत्व पर इनपुट फ़ंक्शन को लागू करके और एक नए IEnumerable के अंदर परिणामों को लपेटकर अपने आउटपुट का उत्पादन करेगा।

    कुछ गणित जैसे संकेतन का उपयोग करते हुए, यह इनपुट (a, b, c, ...) के रूप में लेता है : IEnumerable <T1> और f: T1 → T2 और उत्पादन (f (a), f (b), f (c) , ...): IEnumerable <T2>

  • कहां: (IEnumerable <T1>, Func <T1, bool>) → IEnumerable <<11> ; यह टाइप 1 के IEnumerable वाले तत्वों को लेता है और T1 पर एक विधेय (जो कि, एक ऐसा फ़ंक्शन है जो टाइप T1 के इनपुट के लिए बूलियन परिणाम उत्पन्न करता है)। आप देखते हैं कि आउटपुट भी टाइप 1 के IEnumerable तत्वों से युक्त है।

    इस बार कोई अनुमान लगाएगा कि इनपुट IEnumerable का एक तत्व तत्व के लिए विधेय के परिणाम के आधार पर आउटपुट IEnumerable पर मौजूद होगा। ऑपरेटर नाम के शब्दार्थ में इसे जोड़कर, आप यह सुनिश्चित कर सकते हैं कि यह आउटपुट IEnumerable को इनपुट से ले कर केवल उन तत्वों का उत्पादन करेगा जो कि विधेय के आवेदन पर सत्य का मूल्यांकन करता है।

कार्यात्मक प्रोग्रामिंग पृष्ठभूमि वाले लोग आमतौर पर ऐसा सोचते हैं। यह आपको कटौती करने की अनुमति देता है (या कम से कम अनुमान लगा सकता है ...) एक ऑपरेटर केवल इसे देखकर ही करता है!

एक अभ्यास के रूप में, IEnumerables पर LINQ द्वारा शुरू किए गए अन्य ऑपरेटरों को देखने और उनके व्यवहार को कम करने की कोशिश करें, प्रलेखन को देखने से पहले!



18

एक नए ढांचे के लिए नक्शे का चयन करें। यदि आप IEnumerable पर एक चयन करते हैं, तो आपको समान संख्या में तत्वों के साथ एक सरणी मिलेगी, लेकिन आपके द्वारा निर्दिष्ट मैपिंग के आधार पर एक अलग प्रकार। जहां IEnumerable फ़िल्टर करता है ताकि यह आपको मूल IEnumerable का सबसेट प्रदान करे।



7

यदि आप जानते हैं कि उन्होंने कैसे लागू किया है, तो विस्तार कहां और कैसे करें तरीकों का आप अनुमान लगा सकते हैं कि यह क्या कर रहा है ... मैंने कहां लागू करने की कोशिश की है और विस्तार विधियों का चयन करें ... आप इसे देख सकते हैं ...

जहां कार्यान्वयन ::

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

कार्यान्वयन का चयन करें ::

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

मेरा कार्यान्वयन किसी भी संग्रह के लिए ठीक काम करता है ... लेकिन यह Microsoft कार्यान्वित एक्सटेंशन विधियों से भिन्न होता है, क्योंकि वे उसी को लागू करने के लिए अभिव्यक्ति पेड़ों का उपयोग करते हैं।


1

इसे चुनें के मामले में आप एक नई संरचना के IEnumerable में मैप कर सकते हैं।

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

कहां () IEnumerable के लिए एक फिल्टर के रूप में काम करता है, यह परिणाम को उस खंड के आधार पर वापस कर देगा।

A.Where(x=>x.uid!=0) //input as [IEnumerable<A>] -------->  return output as [IEnumerable<A> ]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.