ruby - google - मकान का नक्शा फोटो




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

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

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


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

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

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

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

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

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

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


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

बेंचमार्क कोड यहां दिया गया है:

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) 

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


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

वास्तव में वे ruby-doc.org के तहत एक ही स्थान पर दस्तावेज हैं:

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

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

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

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






collect