From: Robert Klemme Date: 2010-01-07T18:50:11+09:00 Subject: Re: group in the array On 01/07/2010 05:00 AM, Ruby Newbee wrote: > On Thu, Jan 7, 2010 at 11:19 AM, Ruby Newbee wrote: >> On Wed, Jan 6, 2010 at 11:20 PM, Robert Klemme >> wrote: >> >>> inject >>> http://ruby-doc.org/core-1.8.7/classes/Enumerable.html#M001147 >> I have checked the document for inject, but still can't understand for. >> Can you help explain it with general words by a little samples? > Now I checked some other help documents wigh google, and find Ruby's > inject is similiar to Python's reduce, which is known by me. I don't know Python's reduce but a few things are probably noteworthy about Ruby's #inject: It does matter whether you provide an argument or not: irb(main):001:0> (1..5).inject {|*a| p a; nil} [1, 2] [nil, 3] [nil, 4] [nil, 5] => nil irb(main):002:0> (1..5).inject(0) {|*a| p a; nil} [0, 1] [nil, 2] [nil, 3] [nil, 4] [nil, 5] => nil This means that when summing up you usually want to provide 0 as argument. For other use cases, e.g. concatenating you probably do not want to: irb(main):003:0> (1..5).inject(0) {|sum,x| sum + x} => 15 irb(main):004:0> [].inject(0) {|sum,x| sum + x} => 0 Whithout you do not get a sum for the empty collection: irb(main):005:0> [].inject {|sum,x| sum + x} => nil Not providing an argument can be useful as well: irb(main):008:0> (1..5).inject {|a,b| a.to_s << "," << b.to_s} => "1,2,3,4,5" (Of course, that's better done with #join.) And Ruby's pattern matching for block arguments makes it easy to process Hash and other collections that have more than one object per iteration: irb(main):001:0> h={1=>2,3=>4} => {1=>2, 3=>4} irb(main):002:0> h.inject(0) {|sum, (key, val)| sum + key + val} => 10 Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/