From: Robert Klemme Date: 2010-01-09T19:04:47+09:00 Subject: Re: group in the array 2010/1/7 Rick DeNatale : > On Thu, Jan 7, 2010 at 4:50 AM, Robert Klemme > wrote: >> On 01/07/2010 05:00 AM, Ruby Newbee wrote: >> 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 > > Which you may or may not want. I'd say normally you want 0 for an empty collection because that is the neutral element for addition. Any code relying on uniform further processing of the result of summing up the collection will be simpler if 0 is injected for the sum. > I'm not sure I see the logic of why you example alone leads to the > recommendation to provide the 0 argument: Because the empty Enumerable is the one where behavior differs. > ruby-1.8.7-p174 > (1..5).inject(0) {|sum,x| p [sum, x]; sum + x} > [0, 1] > [1, 2] > [3, 3] > [6, 4] > [10, 5] >  => 15 > ruby-1.8.7-p174 > (1..5).inject {|sum,x| p [sum, x]; sum + x} > [1, 2] > [3, 3] > [6, 4] > [10, 5] >  => 15 > > I've come to use inject or reduce depending on whether or not I'm > providing the argument, assuming I'm using a version of Ruby which > aliases them.  I think that inject without an argument is a bit > mysterious, because that argument is what you are injecting. > > I think that most languages which have a form of reduce don't allow > that argument, as far as I know, it came from Smaltalk whose form of > reduce came from the inject:initialValue into: aBlock method on > collection classes. For an old Smaltalker Ruby's inject was no > mystery, but using reduce when not supplying the argument makes more > sense to me. So you are basically saying that you pick the method name depending on whether you provide an argument or not. Actually I had forgotten about #reduce completely. OTOH I use the method rarely nowadays but when I use it I provide an argument most of the time. Kind regards robert PS: Your posting was somehow cut off on my news server. Does anybody else experience the same? The cut was after > This means that when summing up you usually want to provide 0 as argument (~ line 40) -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/