2012-12-14 20 views
22

मुझे कम करने के लिए वाक्यविन्यास में समस्या हो रही है।हैश वैल्यू घटाएं

H = {"Key1" => 1, "Key2" => 2} 

मैं इस समारोह में मानों का योग लगाने के लिए कम करने का उपयोग करना चाहेंगे: मैं निम्न स्वरूप का एक हैश है।

कुछ

तरह
H.reduce(0) {|memo, elem| memo+=elem} 

मैं जानता हूँ कि यह गलत है। मैं समझ नहीं पा रहा हूं कि मैं हाथी के मूल्य को कैसे बना सकता हूं।

+6

कोशिश करें: एच .values.reduce (: +) –

+0

धन्यवाद! जिसने चाल – richsoni

उत्तर

27

उपयोग Enumerable#reduce, यदि आप nil हो रही के साथ ठीक कर रहे हैं हैश होने वाला खाली:

H.values.reduce(:+) # => 3 
Hash.new.values.reduce(:+) # => nil 
0

सुरक्षित रूप से प्राप्त करने के लिए जब हैश खाली, इस्तेमाल होता है:

H.values.reduce(0) { |sum,x| sum + x } # or... 
H.reduce(0) { |sum,(key,val)| sum + val } # ...if you need to inspect the key 

यहाँ किक के लिए, एक त्वरित बेंचमार्क है। ध्यान दें कि यह थोड़ा तेज हो गया लगता है कुंजी/मान जोड़े से मूल्यों के बजाय सिर्फ मूल्यों को कम करने:

       user  system  total  real 
H.values.reduce(:+)  4.510000 0.080000 4.590000 ( 4.595229) 
H.values.reduce(0) {...} 4.660000 0.080000 4.740000 ( 4.739708) 
H.reduce(0) {...}   5.160000 0.070000 5.230000 ( 5.241916) 
require 'benchmark' 

size = 1_000 
hash = Hash[* Array.new(size*2) { rand } ] 

N=10_000 
Benchmark.bm(24) do |x| 
    x.report('H.values.reduce(:+)')  { N.times { hash.dup.values.reduce(:+) } } 
    x.report('H.values.reduce(0) {...}') { N.times { hash.dup.values.reduce(0) { |sum,x| sum + x } } } 
    x.report('H.reduce(0) {...}')  { N.times { hash.dup.reduce(0) { |sum,(_,v)| sum + v } } } 
end 
+0

ध्यान दें कि यदि हैश खाली है तो यह 0 नहीं लौटाता है। आपको ठंडा (कुंजी, वैल) proc arg वाक्यविन्यास के लिए –

1
h = {"Key1" => 1, "Key2" => 2} 

h.values.inject(0){|f,v| f += v.to_i } 
# => 3 

या

h.values.inject(:+) 
# => 3 
4

इस प्रयास करें:

H.reduce(0) { |memo, elem| memo += elem[1] } 

या

H.reduce(0) { |memo, (key, value)| memo += value } 
+1

किया था, मैंने लोगों को यह सोचने से बचने के लिए 'ज्ञापन + मूल्य' लिखा होगा कि 'ज्ञापन' अपडेट करना सहायक है। – lkuty

64

आप elem मान कर सकते हैं 2 चर में इसे विभाजित करके:

H.reduce(0) {|memo, (key, val)| memo += val} 
+10

+1 के नीचे ज्ञापन संस्करण का उपयोग करना होगा! – maerics

+1

यह बहुत खूबसूरत है। – jturolla

+3

लोगों को यह सोचने से बचने के लिए 'memo + val' लिखा होगा कि' ज्ञापन 'अपडेट करना सहायक है। – lkuty

1

मैं जानता हूँ कि मैं इस एक खुदाई कर रहा हूँ, लेकिन अगर आप रेल का उपयोग होता है, .sum method मदद कर सकते हैं:

H = {"Key1" => 1, "Key2" => 2} 
=> {"Key1"=>1, "Key2"=>2} 
> H.values.sum 
=> 3 

लाभ यह है कि यह खाली हैश पर 0 देता है:

> {}.values.sum 
=> 0 
> {}.values.reduce(:+) 
=> nil 

मैंने देखा कि यह केवल इस उत्तर लिखने के बाद रेल विशेष था। मुझे पता है कि ओपी ने रेल टैग नहीं जोड़ा है, लेकिन मुझे लगा कि यह लोगों द्वारा रुकने के लिए उपयोगी हो सकता है।

ध्यान दें कि रूबी 2.4.0, .sum is now available के रूप में।

+1

'.sum' अब रूबी 2 में लागू किया गया है।4 [संख्यात्मक # योग] (https://ruby-doc.org/core-2.4.0/Enumerable.html#method-i-sum)। – user3162553

+0

अच्छी पकड़, मैंने अपने जवाब में एक नोट जोड़ा, धन्यवाद! – astorije

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^