ruby - प्रत्येक के बीच क्या अलग है और रुबी में विधि एकत्रित करें




each collect (5)

अंतर यह है कि यह क्या देता है। आपके उदाहरण a == [nil,nil,nil] (x.succ डालने का मान) जबकि b == ["L", "Z", "J"] (मूल सरणी)

रूबी-डॉक्टर से, संग्रह निम्न करता है:

स्वयं के प्रत्येक तत्व के लिए एक बार ब्लॉक को आमंत्रित करता है। ब्लॉक द्वारा लौटाए गए मानों वाला एक नया सरणी बनाता है।

प्रत्येक हमेशा मूल सरणी देता है। समझ में आता है?

इस प्रश्न का उत्तर यहां दिया गया है:

इस कोड से मैं दो तरीकों, collect और each बीच का अंतर नहीं जानता।

a = ["L","Z","J"].collect{|x| puts x.succ} #=> M AA K 
print  a.class  #=> Array

b = ["L","Z","J"].each{|x| puts x.succ} #=> M AA K
print  b.class #=> Array

प्रत्येक एक वर्ग है जो सभी वर्गों द्वारा परिभाषित किया गया है जिसमें संख्यात्मक मॉड्यूल शामिल है। ऑब्जेक्ट। प्रत्येक एक Object.each Enumerable::Enumerator Object.each वस्तु देता है। ऑब्जेक्ट के माध्यम से पुनरावृत्ति करने के लिए अन्य संख्यात्मक विधियों का उपयोग किया जाता है। each वर्ग के each तरीके अलग-अलग व्यवहार करते हैं।

ऐरे क्लास में जब each ब्लॉक को एक ब्लॉक पास किया each , तो यह प्रत्येक तत्व पर ब्लॉक के बयान करता है, लेकिन अंत में स्वयं लौटाता है। यह तब उपयोगी होता है जब आपको सरणी की आवश्यकता नहीं होती है, लेकिन हो सकता है कि आप शायद तत्वों को चुनना चाहें सरणी और अन्य विधियों के लिए तर्क के रूप में उपयोग करें। प्रत्येक तत्व पर ब्लॉक के निष्पादन के वापसी मूल्यों के साथ inspect और map एक नई सरणी लौटाएं। आप map! उपयोग कर सकते हैं map! और collect! मूल सरणी पर संचालन करने के लिए।


docs अनुसार, दो स्रोत कोड स्निपेट हैं ...

VALUE
rb_ary_each(VALUE ary)
{
    long i;

    RETURN_ENUMERATOR(ary, 0, 0);
    for (i=0; i<RARRAY_LEN(ary); i++) {
        rb_yield(RARRAY_PTR(ary)[i]);
    }
    return ary;
}

# .... .... .... .... .... .... .... .... .... .... .... ....

static VALUE
rb_ary_collect(VALUE ary)
{
    long i;
    VALUE collect;

    RETURN_ENUMERATOR(ary, 0, 0);
    collect = rb_ary_new2(RARRAY_LEN(ary));
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        rb_ary_push(collect, rb_yield(RARRAY_PTR(ary)[i]));
    }
    return collect;
}

rb_yield() ब्लॉक द्वारा लौटाए गए मान को लौटाता है rb_yield() पर यह ब्लॉग पोस्ट भी देखें )।

इसलिए each मूल उप सरणी उत्पन्न करता है और देता है, जबकि collect एक नई सरणी बनाता है और इसमें ब्लॉक के परिणाम को धक्का देता है; तो यह इस नई सरणी देता है।

स्रोत स्निपेट: each , collect


Array#each एक सरणी लेता है और सभी वस्तुओं पर दिए गए ब्लॉक को लागू करता है। यह सरणी को प्रभावित नहीं करता है या एक नई वस्तु बनाता है। यह वस्तुओं पर लूपिंग का एक तरीका है। इसके अलावा यह स्वयं लौटता है।

  arr=[1,2,3,4]
  arr.each {|x| puts x*2}

प्रिंट 2,4,6,8 और रिटर्न [1,2,3,4] कोई फर्क नहीं पड़ता कि क्या

Array#collect Array#map समान है और यह सभी वस्तुओं पर कोड के दिए गए ब्लॉक को लागू करता है और नई सरणी देता है। बस 'अनुक्रम के प्रत्येक तत्व को एक नए रूप में प्रोजेक्ट करें'

  arr.collect {|x| x*2}

रिटर्न [2,4,6,8]

और आपके कोड में

 a = ["L","Z","J"].collect{|x| puts x.succ} #=> M AA K 

ए एक ऐरे है लेकिन यह वास्तव में नील की एक सरणी है [शून्य, शून्य, शून्य] क्योंकि puts x.succ रिटर्न nil देता है (भले ही यह एम एए के प्रिंट करता है)।

तथा

 b = ["L","Z","J"].each{|x| puts x.succ} #=> M AA K

एक ऐरे भी है। लेकिन इसका मूल्य ["एल", "जेड", "जे"] है, क्योंकि यह स्वयं लौटाता है।


each उस समय के लिए होता है जब आप किसी सरणी पर पुनरावृत्ति करना चाहते हैं, और प्रत्येक पुनरावृत्ति में जो कुछ भी आप चाहते हैं उसे करें। अधिकांश (अनिवार्य) भाषाओं में, यह "एक आकार सभी फिट बैठता है" हैमर प्रोग्रामर तब तक पहुंचते हैं जब आपको किसी सूची को संसाधित करने की आवश्यकता होती है।

अधिक कार्यात्मक भाषाओं के लिए, आप केवल इस तरह के जेनेरिक पुनरावृत्ति करते हैं यदि आप इसे किसी अन्य तरीके से नहीं कर सकते हैं। अधिकांश समय, या तो मानचित्र या कमी अधिक उपयुक्त होगी (रूबी में एकत्रित करें और इंजेक्ट करें)

collect तब होता है जब आप एक सरणी को किसी अन्य सरणी में बदलना चाहते हैं

inject तब होता है जब आप एक सरणी को एक मान में बदलना चाहते हैं







collect