C # सूची <> में .Any () का क्या उपयोग है?


40

मैं सहकर्मियों के साथ इस बारे में चर्चा कर रहा हूं, और हम यह पता नहीं लगा सके कि .Anyकिसी भी दिए का उपयोग List<>C # में क्या है।

आप निम्न कथन की तरह सरणी में किसी तत्व की वैधता की जांच कर सकते हैं:

if (MyList.Any()){ ...}  //Returns true or false

जो बिल्कुल वैसा ही है

if (MyList.Count() != 0) { ... }

और ifबयान के इरादे के बारे में बहुत अधिक सामान्य, पठनीय और स्पष्ट है ।

अंत में, हम इस सोच के साथ फंस गए:

.Any() इस्तेमाल किया जा सकता है, बस के रूप में अच्छी तरह से काम करेगा, लेकिन प्रोग्रामर के इरादे के बारे में कम स्पष्ट है, और यह मामला है कि इसका इस्तेमाल नहीं किया जाना चाहिए।

लेकिन हमें लगता है कि यह सही नहीं हो सकता; हमें कुछ याद आ रहा है।

क्या हम?


40
किस तरह से इरादे पर कोई कम स्पष्ट है?
जे.के.

35
मैं आपके दावे को चुनौती देता हूं जो Any()कम स्पष्ट है: Any()मेरे लिए अधिक स्पष्ट लगता है, विशेष रूप से एक लंब-हालत के साथ। मेरे सिर में अंग्रेजी के लिए कोड का अनुवाद, if(MyList.Count(o => o > 10) > 0)हो जाता है "मदों की संख्या 10 से अधिक 0 से अधिक है?" जबकि if(MyList.Any(o => o > 10))हो जाता है "वहाँ किसी भी आइटम 10 से अधिक कर रहे हैं?"
ब्लूराजा - डैनी पफ्लुगुएफ्ट

3
@ सर्जबॉर्श - केवल यदि आप Heskel / कार्यात्मक नामकरण पसंद करते हैं, जो ज्यादातर लोग नहीं करते हैं।
atद्रालो

4
@ BlueRaja-DannyPflughoeft मैं सहमत हूं। मुझे लगता है कि कोई भी अधिक स्पष्ट है क्योंकि यह एक जादू की संख्या को माना जा सकता है।
एंडी

2
@ सर्जबॉर्श: एसक्यूएल समानांतर Anyहै Exists। लिनक नाम संभवतः हास्केल और पायथन से अधिक प्रेरित है जिसमें कोई भी / सभी कार्य हैं।
जैक्सबी

जवाबों:


95

ध्यान रखें कि Anyएक पर काम नहीं करता है List; यह एक पर संचालित होता है IEnumerable, जो एक ठोस प्रकार का प्रतिनिधित्व करता है जो एक Countसंपत्ति हो सकता है या नहीं हो सकता है । यह सच है कि यह जरूरी नहीं कि सबसे अच्छी चीज है List, लेकिन यह निश्चित रूप से एक LINQ क्वेरी के अंत में काम आता है। और स्टैंडअलोन संस्करण की तुलना में अधिक उपयोगी भी ओवरराइड है जो एक विधेय की तरह लेता है Where। वहाँ पर कुछ भी नहीं बनाया गया है Listकि कहीं भी निकट या Anyविस्तारक विधि के रूप में सुविधाजनक के रूप में अभिव्यंजक है ।

इसके अलावा, यदि आप Count()(IEnumerable के लिए LINQ एक्सटेंशन विधि) का उपयोग कर रहे हैं , बजाय Count(संपत्ति पर List), तो यहCount पूरे अनुक्रम को एन्यूमरेट करना पड़ सकता है, यदि यह पता लगाकर इसे दूर नहीं कर सकता है कि आपके अंतर्निहित डेटा प्रकार में एक संपत्ति है । यदि आपके पास एक लंबा अनुक्रम है, तो यह ध्यान देने योग्य प्रदर्शन हिट हो सकता है जब आप वास्तव में इस बात की परवाह नहीं करते हैं कि क्या है, और सिर्फ यह जानना चाहते हैं कि क्या संग्रह में कोई आइटम हैं ।


19
यह। प्रदर्शन एक तरफ, Any()विधेय के साथ है और अधिक अर्थपूर्ण से की ओवरराइड की तुलना Enumerable.Count()कि 0. साथ :) एक विधेय लेता है
दान जम्मू

1
मुझे लगता है कि यह मूल सिद्धांतों को इतनी स्पष्ट रूप से व्याख्या करता है कि सबसे अच्छा उत्तर बताता है।
तारिक

2
IMHO, एक विधेय के समान Existsही सुविधाजनक और अभिव्यंजक Anyहै। उपयोग की तुलना में Count != 0संपत्ति पर संपत्ति का उपयोग करना Listअधिक सामान्य है Any()। यह सिर्फ व्यक्तिगत प्राथमिकता है। मैं भी बदलने की प्रयास के माध्यम से चले गए हैं _list_.Count()करने के लिए _list_.Countअपने समूह के कोड में। इसने मुझे ध्यान देने योग्य अंतर पैदा किया।
Suncat2000

55

एक रन टाइम अंतर Count()है O (n) जहां Any()O (1) हो सकता है।


15
Count()अनंत पुनरावृत्तियों के लिए भी रुकना नहीं होगा, जबकि Any()यह केवल MoveNext()एक बार कॉल करने की आवश्यकता है ।
जॉन प्यूडी

3
रसीला और सटीक, लेकिन यह एक उत्तर की तुलना में टिप्पणी के रूप में अधिक पढ़ता है। प्रोग्रामर जवाब देना पसंद करते हैं कि क्यों इसमें देरी हुई और स्पष्टीकरण का एक उपाय प्रदान किया गया । अपने जवाब को संपादित करने पर विचार करें और O (1) क्यों महत्वपूर्ण हो सकता है, इस पर विस्तार करना।

बहुत अच्छा जवाब बस सीखा मैं गिनती के बजाय किसी भी उपयोग करना चाहिए == 0: d
मॉन्स्टरमोरपीजी


1
के विशिष्ट मामले में List, प्रदर्शन समान है क्योंकि एक्सटेंशन संपत्ति का उपयोग करता है। ICollectionइंटरफ़ेस को लागू करने वाले सभी संग्रहों के लिए सही है ।
थोरिल होल्म-जैकबसेन

9

दरअसल, ध्यान रखें कि List.Count प्रॉपर्टी है, और फिर Enumerable.Count मेथड है।

आपके उदाहरण में, आप Enumerable.Count()विधि का उपयोग कर रहे हैं , जिसके परिणामस्वरूप परिणाम को वापस करने के लिए गणना के हर एक आइटम के माध्यम से पुनरावृति करना है। यह स्पष्ट रूप से कॉल करने की तुलना में धीमा है Any()जो केवल पहले आइटम पर पुनरावृति करने की आवश्यकता है, अगर यह मौजूद है।

संपादित करें:

टिप्पणियों में यह कहा गया था, ठीक है, तो उस Enumerable.Count()विस्तार पद्धति को सभी वस्तुओं के माध्यम से पुनरावृति करने की आवश्यकता नहीं है यदि यह पता लगाता है कि गणना करने योग्य भी एक होना चाहिए ICollection<T>। इसलिए List<T>, Countसंपत्ति या विधि का उपयोग करने के मामले में वास्तव में कोई फर्क नहीं पड़ता है।

IEnumerable.Count स्रोत:

public static int Count<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    ICollection<TSource> collectionoft = source as ICollection<TSource>;
    if (collectionoft != null) return collectionoft.Count;
    ICollection collection = source as ICollection;
    if (collection != null) return collection.Count;
    int count = 0;
    using (IEnumerator<TSource> e = source.GetEnumerator()) {
        checked {
            while (e.MoveNext()) count++;
        }
    }
    return count;
}

काफी उचित। के उपयोग के बारे में क्या है। फिर संपत्ति? ऐसा नहीं है कि पढ़ने में काफी तेजी से, शायद के रूप में उपवास या फोन करने की तुलना में भी तेजी से। ()?
गिल सैंड

4
एक साथ List<T>प्रदर्शन अंतर नगण्य हो जाएगा। इसलिए जो आप पसंद करते हैं, उसका उपयोग करें। लेकिन अन्य प्रकार के IEnumerables के लिए, आपको केवल Count()(विधि) लेने के लिए मिलता है Any(), और उस स्थिति में, Any()हमेशा आपके उपयोग के मामले के लिए स्पष्ट विजेता होगा और इसे प्राथमिकता दी जानी चाहिए। इसके लायक क्या है, मुझे लगता Any()है कि यह काफी पठनीय और स्पष्ट है।
सिस्टर

जब तक ienumerable को कोलाज में डाला जा सकता है तो @sstan हाँ तब तक इसे ऑप्टिमाइज़ किया जा सकता है और इससे कोई फर्क नहीं पड़ेगा।
एबेन स्कोव पेडर्सन

2
Count()के रूप में ही जटिलता है Countके लिए ICollectionके बाद से विस्तार विधि तो बार-बार दोहराना के बजाय संपत्ति का उपयोग करता है, रों।
थोरिल होल्म-जैकबसेन

Linq एक्सटेंशन को ज्ञात इंटरफेस के लिए अनुकूलित किया जाता है - IList, ICollection। यहां पर प्रदर्शन चर्चा पूरी तरह से निरर्थक है, भले ही वह कार्यान्वयन विवरण हो
गुस्सोर

6

एक आश्चर्यजनक सवाल - मुझे लगता है कि इरादे से list.Any()बहुत स्पष्ट होने का इरादा है list.Count()!=0

आशय का अर्थ है: यदि आप किसी को कोड पढ़ते हैं (और आपने इसे स्वयं नहीं लिखा है), तो क्या यह पूरी तरह से स्पष्ट है कि प्रोग्रामर क्या हासिल करना चाहता है और उसने ऐसा क्यों लिखा है? यदि एक सामान्य समस्या को एक अनावश्यक रूप से जटिल तरीके से हल किया जाता है, तो आपको तुरंत संदेह हो जाता है और आश्चर्य होता है कि डेवलपर ने सरल तरीके का उपयोग क्यों नहीं किया। आप कोड को देखते हैं और यह देखने की कोशिश करते हैं कि क्या आपने कुछ मिस किया है। आप कोड बदलने से डरते हैं क्योंकि आप चिंता करते हैं कि कुछ दुष्प्रभाव हैं जो आप गायब हैं और इसे बदलने से अप्रत्याशित समस्याएं हो सकती हैं।

Any()विधि का उपयोग करने का इरादा पूरी तरह से स्पष्ट है - आप जानना चाहते हैं कि सूची में कोई तत्व हैं या नहीं।

Count()!=0दूसरी ओर अभिव्यक्ति की मंशा पाठक के लिए स्पष्ट नहीं है। यह देखना मुश्किल नहीं है कि अभिव्यक्ति आपको बताती है कि सूची खाली है या नहीं। प्रश्न उठते हैं क्योंकि आप इसे मानक विधि का उपयोग करने के बजाय इसे विशेष रूप से लिखते हैं। आप Count()स्पष्ट रूप से क्यों उपयोग करते हैं ? यदि आपको वास्तव में यह जानने की आवश्यकता है कि क्या किसी सूची में कोई तत्व हैं , तो आप पूरी सूची को पहले क्यों गिनना चाहते हैं? जैसे ही आप 1 पर पहुंचते हैं, आपके पास पहले से ही आपका जवाब होता है। यदि स्रोत एक बड़े (शायद अनंत) संग्रह पर एक पुनरावृत्तिकर्ता था या एसक्यूएल में अनुवाद किया जाता है, तो यह एक बड़े अंतर प्रदर्शन को बुद्धिमान बना सकता है। तो हो सकता है कि गणना का स्पष्ट उपयोग () एक स्थगित क्वेरी को निष्पादित करने या एक पुनरावृत्ति करने के लिए मजबूर करने के लिए है?

लेकिन स्रोत वास्तव में ओ (1) है List<T>जहां Count()कोई दुष्प्रभाव नहीं है। लेकिन अगर कोड इस संपत्ति के आधार पर निर्भर करता है List<T>, तो क्यों नहीं Count-प्रोपरेटरी का उपयोग करें जो कि अधिक स्पष्ट रूप से इंगित करता है कि आप ओ (1) ऑपरेशन की उम्मीद करते हैं जिसका कोई साइड इफेक्ट नहीं है?

जैसा कि लिखा गया है, list.Count()!=0बिल्कुल वैसा ही करता है list.Any()सिवाय इसके कि यह अनावश्यक रूप से अधिक जटिल है और इरादा स्पष्ट नहीं है।


मैंने दोनों को इस रूप में पढ़ा, "क्या सूची में कोई आइटम है?" Count()एक निहित रूपांतरण है जिसका मैं उपयोग करने से बचूंगा, लेकिन यह अस्पष्ट नहीं है। संकलक इसे दूर अनुकूलित कर सकता है, जो केवल इसे लापरवाह कोडिंग बनाता है।
सनकैट

2

शायद यह सिर्फ शब्द है? Anyएक विशेषण है, वास्तव में कुछ भी नहीं कह रहा है। जावा से आ रहा है, मैं इसे isNonEmptyएक क्रिया कहते हैं। एक SQL लड़का पसंद कर सकता है EXISTS। लेकिन शायद AnyC # सिस्टम में सबसे अच्छा फिट बैठता है।

शब्द का विकल्प जो भी हो, एक बार जब आप इसकी आदत डाल लेते हैं, तो यह रास्ता साफ होना चाहिए। क्या आप पूछेंगे "क्या more than zeroबीयर की बोतलें बची हैं"। क्या आप one or moreउन लोगों से अपेक्षा करेंगे कि वे "नहीं, नहीं है" का जवाब देने से पहले उन्हें गिनना शुरू कर देंगे any


1
जब आप LINQ के संदर्भ में सोचते हैं तो यह "किसी भी" का अर्थ समझ में आता है: Any()वास्तव में इसके लिए एक शॉर्टकट हैAny(o => true)
BlueRaja - Danny Pflughoeft

मैं आमतौर पर वर्णन करने के लिए खाली का उपयोग नहीं करूंगा कि क्या किसी गणनीय को किसी भी तरह की गणना करने की आवश्यकता थी। लेकिन "वहाँ किसी भी चीज़ की गणना करने के लिए" मुझे स्वाभाविक लगता है, और किसी भी गणना के खिलाफ कोई भी काम करता है।
एंडी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.