2010-03-22 18 views
9

मैं एक रेल ऐप्लिकेशन बनाने में कर रहा हूँ और मेरी तरीकोंमुझे यह काम करने के लिए इंजेक्ट करने के बजाय .inject (0) का उपयोग करने की आवश्यकता क्यों है?

item_numbers.inject(0) {|sum, i| sum + i.amount} 

ITEM_NUMBERS में से एक में इस कोड का इस्तेमाल किया है मेरी ITEM_NUMBERS मेज से वस्तुओं की एक सरणी है। .Mount विधि जो मैं उन पर लागू करता हूं, एक अलग तालिका में item_number का मान देखता है और इसे BigDecimal ऑब्जेक्ट के रूप में देता है। जाहिर है इंजेक्शन विधि तब सभी लौटाई i.amount ऑब्जेक्ट्स जोड़ती है और यह ठीक काम करती है।

मैं क्यों यह काम नहीं किया जब मैं इन बराबर किया जाना चाहिए

item_numbers.inject {|sum, i| sum + i.amount} 

के रूप में इस बयान ने लिखा है मेरे भरोसेमंद गैंती पुस्तक के अनुसार के रूप में बस उत्सुक हूँ। क्या ऐसा इसलिए है क्योंकि i.amount एक BigDecimal है? यदि हां, तो अब यह क्यों काम करता है? यदि नहीं, तो यह क्यों काम नहीं करता है।

उत्तर

14

क्या हम एपीआई में पढ़ सकते हैं:।

आप स्पष्ट रूप से एकनिर्दिष्ट नहीं करते हैंमेमो के लिए प्रारंभिक मान, फिर संग्रह का पहला तत्व मेमो के प्रारंभिक मान के रूप में उपयोग किया जाता है।

तो item_numbers [0] प्रारंभिक मान के रूप में निर्दिष्ट किया जाएगा - लेकिन यह एक संख्या नहीं है, यह एक वस्तु है। तो हमें एक त्रुटि मिली है

अपरिभाषित विधि `+ '। योग, मैं |

तो हम के रूप में 0

item_numbers.inject (0) {प्रारंभिक मूल्य निर्दिष्ट करना | योग + i}

+0

आप एक छोटे से परीक्षण (10..15) .inject कर ऐसा कर सकते हैं | योग, मैं | पी योग योग + मैं अंत यह वापस आ जाएगी: 10, 21, 33, 46, 60 => 75 आप _sum_ देख सकते हैं प्रारंभिक मूल्य – fl00r

+0

कि यह अच्छी तरह से बताते हैं के रूप में सरणी से पहले आइटम हो जाता है। धन्यवाद। – brad

7

ऐसा इसलिए है क्योंकि आप केवल के विपरीत i.amount तक पहुंच रहे हैं। संस्करण में जो काम नहीं करता है, आप पूरी तरह से item_numbers[0] + item_numbers[1].amount + ... कर रहे हैं।

एक शॉर्टेंड item_numbers.map(&:amount).inject(&:+) होगा, लेकिन इस तरह से सूची में दो पुनरावृत्तियों का परिणाम हो सकता है, यदि map एक गणक वापस नहीं करता है।

है कि आप को समझाने नहीं था, क्या बाहर प्रिंट हो अगर हम Fixnum पर एक विधि amount कि यह लौटने से पहले मूल्य प्रिंट परिभाषित देखो:

irb(main):002:1> def amount 
irb(main):003:2>  puts "My amount is: #{self}" 
irb(main):004:2>  return self 
irb(main):005:2> end 
irb(main):006:1> end 
=> nil 
irb(main):007:0> [1,2,3].inject { |sum, i| sum + i.amount } 
My amount is: 2 
My amount is: 3 
=> 6 
irb(main):008:0> [1,2,3].inject(0) { |sum, i| sum + i.amount } 
My amount is: 1 
My amount is: 2 
My amount is: 3 
=> 6 
irb(main):009:0> 

हम देख सकते हैं स्पष्ट रूप से है कि amount नहीं बुलाया जाता है एक प्रारंभिक मूल्य को स्पष्ट रूप में पारित पहले तत्व पर जब नहीं

+0

+1 स्पष्ट उदाहरण के लिए जो व्यवहार को दिखाता है पूरी तरह से – Jean

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

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