On 9/5/06, Phrogz <gavin / refinery.com> 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/