From: Rick DeNatale Date: 2006-09-06T04:22:44+09:00 Subject: Re: Modifying the first value with #inject On 9/5/06, Phrogz wrote: > Is there an idiom for doing something to the first value as part of an > inject? Or do I need to .map{}.inject{}? > > class Array > def sum > inject(0){ |total, entry| total + entry.to_f } > end > def product > inject(1){ |total, entry| total * entry.to_f } > end > def running_difference > inject{ |total, entry| total - entry.to_f } use inject(0) { |total, entry| total / entry.to_f } or inject { |total, entry| total.to_f / entry.to_f } here > end > def running_divide > inject{ |total, entry| total / entry.to_f } use inject{ |total, entry| total.to_f / entry.to_f } here > end > end What's happening is that inject without the argument uses the first element of the enumerable as the initial value, and skips it in the iteration. > a2 = ["5","4","3","2","1"] > p a2.sum > #=> 15.0 > p a2.product > #=> 120.0 These both work you are supplying the intial value of 0 and 1 respectively and the Numerics convert the arguments of +, and * to numerics. > p a2.running_difference > #=> tmp.rb:9:in `running_difference': undefined method `-' for > "5":String (NoMethodError) > #=> from tmp.rb:36:in `inject' > #=> from tmp.rb:9:in `running_difference' > #=> from tmp.rb:31 Since you haven't specified an initial value for the inject here the first iteration is trying to do "5" - "4".to_f which doesn't work. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/