On 01/07/2010 05:00 AM, Ruby N. wrote:
On Thu, Jan 7, 2010 at 11:19 AM, Ruby N. [email protected] wrote:
On Wed, Jan 6, 2010 at 11:20 PM, Robert K.
[email protected] wrote:
inject
Module: Enumerable (Ruby 1.8.7)
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