रूबी में मानचित्र और संग्रह के बीच अंतर?


427

मैंने इसे Googled और पैची / विरोधाभासी राय प्राप्त की - क्या वास्तव में रूबी / रेल में एक सरणी पर mapकर और कर के बीच कोई अंतर है collect?

डॉक्स किसी भी सुझाव देने के लिए नहीं है, लेकिन वहाँ शायद विधि या प्रदर्शन में अंतर कर रहे हैं?


5
mapकोड गोल्फ में पसंद किया जाता है ।
कैरी स्वेवेलैंड

1
mapकोडगॉल्फ में क्यों पसंद किया जाता है, इसके स्पष्टीकरण के रूप में, जो सभी के लिए स्पष्ट नहीं हो सकता है: यह केवल इसलिए collectहै क्योंकि चार वर्णों की तुलना में लंबा है map, लेकिन कार्यक्षमता में समान है।
जोकेम शुल्नेक्लोपर

2
सिर्फ शैतान के वकील की भूमिका निभाने के लिए, मैं व्यक्तिगत रूप से collectअधिक पठनीय और स्वाभाविक पाता हूं - 'संग्रह' रिकॉर्ड करने और उनके लिए एक्स करने का विचार मेरे लिए 'मैपिंग' रिकॉर्ड और उनके लिए एक्स करने की तुलना में अधिक प्राकृतिक अर्थ रखता है।
sscirrus

जवाबों:


479

कोई अंतर नहीं है, वास्तव mapमें सी के रूप में कार्यान्वित किया जाता है rb_ary_collectऔर enum_collect(जैसे। mapएक सरणी पर और किसी भी अन्य एनम के बीच अंतर है, लेकिन बीच कोई अंतर नहीं है mapऔर collect)।


दोनों क्यों mapऔर collectरूबी में मौजूद हैं? mapसमारोह विभिन्न भाषाओं में कई नामकरण सम्मेलनों है। विकिपीडिया एक सिंहावलोकन प्रदान करता है :

मानचित्र फ़ंक्शन का आरंभ कार्यात्मक प्रोग्रामिंग भाषाओं में हुआ है, लेकिन आज भी समर्थित है (या परिभाषित किया जा सकता है) कई प्रक्रियात्मक, वस्तु उन्मुख, और बहु-प्रतिमान भाषाओं में भी: C ++ की स्टैंडर्ड टेम्प्लेट लाइब्रेरी में, इसे transformC # (3.0 अंक) में कहा जाता है । LINQ लाइब्रेरी, इसे विस्तार विधि के रूप में प्रदान किया जाता है Select। नक्शा उच्च स्तरीय भाषाओं जैसे कि पर्ल, पायथन और रूबी में अक्सर उपयोग किया जाने वाला ऑपरेशन है; ऑपरेशन को mapइन तीनों भाषाओं में कहा जाता है। रूबी (स्मालटाक से) [जोर मेरा] में मानचित्र के लिए एक collectउपनाम भी प्रदान किया गया है । कॉमन लिस्प, नक्शे जैसे कार्यों का एक परिवार प्रदान करता है; यहां वर्णित व्यवहार के अनुरूप एक को mapcar(कार संचालन का उपयोग करके संकेत का संकेत मिलता है) कहा जाता है ।

रूबी घर पर और अधिक महसूस करने के लिए स्मॉलटॉक दुनिया के प्रोग्रामर के लिए एक उपनाम प्रदान करती है।


ऐरे और एनम के लिए एक अलग कार्यान्वयन क्यों है? एनम एक सामान्यीकृत पुनरावृत्ति संरचना है, जिसका अर्थ है कि कोई रास्ता नहीं है जिसमें रूबी भविष्यवाणी कर सकती है कि अगला तत्व क्या हो सकता है (आप अनंत एनमों को परिभाषित कर सकते हैं, एक उदाहरण के लिए प्राइम देखें )। इसलिए प्रत्येक क्रमिक तत्व को प्राप्त करने के लिए एक फ़ंक्शन को कॉल करना चाहिए (आमतौर पर यह eachविधि होगी )।

Arrays सबसे आम संग्रह है, इसलिए उनके प्रदर्शन का अनुकूलन करना उचित है। चूंकि रूबी बहुत कुछ जानती है कि एरे कैसे काम करता है, इसके लिए उसे कॉल करने की ज़रूरत नहीं है, eachलेकिन केवल सरल पॉइंटर हेरफेर का उपयोग कर सकता है जो कि काफी तेज है।

इसी तरह के अनुकूलन कई ऐरे तरीकों के लिए मौजूद हैं zipया जैसे count


13
@ मर्क रीड, लेकिन फिर, स्मॉलटॉक से नहीं आने वाले प्रोग्रामर दो अलग-अलग फ़ंक्शन होने से कंफ्यूज हो जाते हैं, जो कि सिर्फ एलियासेस हैं। यह ऊपर ओपी एक जैसे सवालों का कारण बनता है।
5

10
@ सासक मैं असहमत नहीं हूँ - मुझे लगता है कि यह बेहतर होगा यदि केवल एक ही नाम था। लेकिन रूबी में अन्य उपनामों के बहुत सारे हैं, और अलियासिंग से एक सुविधा एक अच्छा नामकरण समानांतर यह है कि बीच में संचालन है इकट्ठा , का पता लगाने , सुई , अस्वीकार , और चयन (अन्यथा रूप में जाना जाता नक्शा , लगता है , को कम करने , अस्वीकार (कोई अन्य नाम ), और find_all )।
मार्क रीड

4
वास्तव में। जाहिर है, रूबी अधिक अवसरों पर उपनाम / समानार्थक शब्द का उपयोग कर रहा है। उदाहरण के लिए, एक सरणी में तत्वों की संख्या के साथ प्राप्त किया जा सकता है count, lengthया, size। किसी सरणी की समान विशेषता के लिए अलग-अलग शब्द, लेकिन इसके द्वारा, रूबी आपको अपने कोड के लिए सबसे उपयुक्त शब्द चुनने में सक्षम बनाता है: क्या आप चाहते हैं कि आपके द्वारा संग्रहित वस्तुओं की संख्या , किसी सरणी की लंबाई , या वर्तमान आकार हो । संरचना। अनिवार्य रूप से, वे सभी समान हैं, लेकिन सही शब्द चुनने पर आपके कोड को पढ़ना आसान हो सकता है, जो भाषा का एक अच्छा गुण है।
जोकेम शुल्नेक्लोपर

51

मुझे बताया गया है कि वे समान हैं।

वास्तव में वे रूबी- doc.org के तहत उसी स्थान पर प्रलेखित हैं:

http://www.ruby-doc.org/core/classes/Array.html#M000249

  • ary.collect {| आइटम | ब्लॉक} → new_ary
  • ary.map {| आइटम | ब्लॉक} → new_ary
  • ary.collect → a_enumerator
  • ary.map → a_enumerator

स्वयं के प्रत्येक तत्व के लिए एक बार ब्लॉक को आमंत्रित करता है। ब्लॉक द्वारा लौटाए गए मानों से युक्त एक नई सरणी बनाता है। Enumerable # लीजिए भी देखें।
यदि कोई ब्लॉक नहीं दिया जाता है, तो इसके बजाय एक एन्यूमरेटर लौटाया जाता है।

a = [ "a", "b", "c", "d" ]
a.collect {|x| x + "!" }   #=> ["a!", "b!", "c!", "d!"]
a                          #=> ["a", "b", "c", "d"]

2
बस पूरी तरह से होने के लिए: http://www.ruby-doc.org/core/classes/Enumerable.html#method-i-map
आंद्रे हेलबर्ग

13

मैंने इस प्रश्न का उत्तर देने के लिए एक बेंचमार्क परीक्षण किया, फिर इस पोस्ट को पाया, इसलिए यहां मेरे निष्कर्ष हैं (जो अन्य उत्तरों से थोड़ा भिन्न हैं)

यहाँ बेंचमार्क कोड है:

require 'benchmark'

h = { abc: 'hello', 'another_key' => 123, 4567 => 'third' }
a = 1..10
many = 500_000

Benchmark.bm do |b|
  GC.start

  b.report("hash keys collect") do
    many.times do
      h.keys.collect(&:to_s)
    end
  end

  GC.start

  b.report("hash keys map") do
    many.times do
      h.keys.map(&:to_s)
    end
  end

  GC.start

  b.report("array collect") do
    many.times do
      a.collect(&:to_s)
    end
  end

  GC.start

  b.report("array map") do
    many.times do
      a.map(&:to_s)
    end
  end
end

और मुझे जो परिणाम मिले वो थे:

                   user     system      total        real
hash keys collect  0.540000   0.000000   0.540000 (  0.570994)
hash keys map      0.500000   0.010000   0.510000 (  0.517126)
array collect      1.670000   0.020000   1.690000 (  1.731233)
array map          1.680000   0.020000   1.700000 (  1.744398) 

शायद एक उपनाम मुफ्त नहीं है?


1
मुझे यकीन नहीं है कि ये अंतर महत्वपूर्ण हैं। फिर से दौड़ने पर मुझे गति में अलग-अलग परिणाम मिलते हैं (भले ही आपका हैश कलेक्ट धीमा लगता हो, आपकी सरणी तेजी से लगती है)
murb

10

collectऔर collect!तरीकों के उपनाम हैं mapऔर map!, इसलिए वे एक दूसरे के स्थान में इस्तेमाल किया जा सकता है। इसकी पुष्टि करने का एक आसान तरीका यहां दिया गया है:

Array.instance_method(:map) == Array.instance_method(:collect)
 => true

7

रूबी एलियास विधि # ऐरे # मानचित्र को इकट्ठा करें; वे एक दूसरे का उपयोग किया जा सकता है। (रूबी भिक्षु)

दूसरे शब्दों में, समान स्रोत कोड:

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

RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
collect = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
    rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
}
return collect;
}

http://ruby-doc.org/core-2.2.0/Array.html#method-i-map


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