2010-08-17 17 views
15

मैं वर्तमान में एफ # सीख रहा हूं और मुझे वास्तव में yield! (उपज-बैंग) ऑपरेटर पसंद है। न केवल इसके नाम के लिए बल्कि इसके लिए भी क्या करता है।एफ # उपज! ऑपरेटर - कार्यान्वयन और संभव सी # समकक्ष

yield! ऑपरेटर मूल रूप से आपको अनुक्रम अभिव्यक्ति से अनुक्रम के सभी तत्वों को उपज करने की अनुमति देता है। यह गणक लिखने के लिए उपयोगी है। चूंकि मैं नियमित रूप से बड़े, जटिल गणनाकर्ताओं से मुकाबला करता हूं, इसलिए मुझे उन रणनीतियों में दिलचस्पी है जो हम उन्हें तोड़ने और उन्हें सरल समकक्षों से लिखने के लिए उपयोग कर सकते हैं।

दुर्भाग्यवश, yield! ऑपरेटर सी # में उपलब्ध नहीं है। जहां तक ​​मैं समझता हूँ, यह क्या करता है एक foreach (var x in source) yield x; की तरह है, लेकिन पुस्तक मैं पढ़ रहा हूँ (Petricek's Real World F# - Manning) चलता है कि यह बेहतर प्रदर्शन किया है कि ...

  • तो क्या एफ # संकलक यहाँ कर बिल्कुल करता है? (हाँ, मैं इसे परावर्तक का उपयोग करके भी देख सकता हूं लेकिन मैं तंत्र का अधिक विस्तृत विवरण प्राप्त करना चाहता हूं)।

क्रम सी # मैं कई तरीके का पता लगाया है, लेकिन उनमें से कोई yield! ऑपरेटर के रूप में के रूप में संक्षिप्त है और मैं भी उनमें से जटिलता के बारे में यकीन नहीं है में एक ऐसी ही निर्माण को प्राप्त करने के। क्या कोई मेरी जानकारी दे सकता है अगर मेरे बिगओ नंबर सही हैं? कई निजी प्रगणक में

  • विघटित प्रगणक और उसके बाद सार्वजनिक प्रगणक से प्रत्येक तत्व उपज:

    foreach (var x in part1()) yield x 
    foreach (var x in part2()) yield x 
    

    यह प्रभावी रूप से प्रत्येक तत्व पर एक "डबल उपज" का परिणाम देगा। क्या वह ओ (2 एन) है? (या संभवतः बदतर?) वैसे भी, इस दृष्टिकोण का उपयोग करके मुझे अपने किसी भी उप-वर्ग से yield break; का उपयोग करने से रोक दिया जाता है। कई निजी प्रगणक और फिर concat सार्वजनिक प्रगणक के सभी निजी प्रगणक में

  • विघटित प्रगणक:

    return part1().Concat(part2()) 
    

    मेरा मानना ​​है कि यह ऊपर उल्लिखित समाधान क्योंकि Concat() तरह से मैं ऊपर उल्लिखित कार्यान्वित किया जाता है से अलग नहीं है।

कोई अन्य विकल्प?

उत्तर

6

के बारे में कैसे संकलक तब्दील yield! आपरेशन, the paper उसके जवाब में थॉमस लेवेस्क द्वारा उद्धृत धारा 4.3 में एक कार्यान्वयन तकनीक को दिखाता है (विशेष रूप से, उनके उदाहरण फैले आंकड़े 7-9 सामान्य रणनीति का उदाहरण है)। मुझे नहीं लगता कि सी # में एक पुनरावर्तक ब्लॉक के भीतर से ऐसा करने का कोई अच्छा तरीका है - क्योंकि मैं आपके प्रस्तावित समाधानों को समझता हूं, वे दोनों बार-बार उपयोग किए जाने पर वर्गबद्ध व्यवहार में परिणाम दे सकते हैं। प्रदर्शन लाभ प्राप्त करने के लिए आप मैन्युअल रूप से NestedEnumerable<T> सबक्लास बना सकते हैं, लेकिन यह सामान्य इटरेटर ब्लॉक का उपयोग करने की तुलना में काफी बदसूरत होगा।

7

सी # के वर्तमान संस्करण में, मुझे नहीं लगता कि आपके पास foreach... yield return और Concat से अन्य विकल्प हैं। मैं मानता हूं कि yield! ऑपरेटर सी # में अच्छा होगा, यह निश्चित रूप से कुछ अधिक सुरुचिपूर्ण बनाता है, लेकिन मुझे संदेह है कि यह सुविधा कभी भी "जरूरी" सूची में आ जाएगी, क्योंकि हम आसानी से इसके बिना कर सकते हैं।

आप इस MS research paper है, जो एक नया yield foreach निर्माण का परिचय में रुचि हो सकती:

IEnumerable<XmlNode> Traverse(XmlNode n) 
{ 
    yield return n; 
    foreach (XmlNode c in n.ChildNodes) 
     yield foreach Traverse(c); 
} 

जटिलता के बारे में अपने प्रश्न के बारे में: दोनों ही मामलों में यह हे (एन) है। ओ (2 एन) का उपयोग नहीं किया जाता है, क्योंकि यह ओ (एन) (रैखिक) के समान जटिलता को दर्शाता है। मुझे नहीं लगता कि आप मौजूदा सी # सुविधाओं के साथ उससे बेहतर कर सकते हैं ...

+1

कागज आप का हवाला देते हैं बताते हैं के रूप में, जब इस्तेमाल किया रिकर्सिवली कि ऐसे मामले हैं जहां 'उपज!' (जो सी # में काल्पनिक 'उपज foreach' के बराबर है) हे (एन) लेकिन' foreach ... उपज वापसी है। ..' ओ (एन^2) है। – kvb

+0

@kvb: ठीक है, वह वही था जिसके बारे में मैं बात कर रहा हूं, क्षमा करें अगर यह स्पष्ट नहीं था। –

3

सी # में yield! के लिए कोई सीधा समकक्ष नहीं है। आप वर्तमान में foreach और yield return के संयोजन से फंस गए हैं।

हालांकि, आईआईआरसी, LINQ कुछ समान प्रदान करता है, अर्थात् SelectMany क्वेरी ऑपरेटर, जो सी # को कई from .. in .. क्लॉज के रूप में अनुवाद करता है।

(मैं आशा करती हूं कि मैं दो अलग अवधारणाओं अप मिश्रण नहीं कर रहा हूँ, लेकिन IIRC, दोनों yield! और SelectMany अनिवार्य रूप से अनुमानों "सपाट" कर रहे हैं;। यानी वस्तुओं की एक पदानुक्रम एक सूची में "चपटा" है।)