# Modifying the first value with #inject

**URL:** <https://www.ruby-forum.com/t/modifying-the-first-value-with-inject/67634>\
**Category:** Ruby\
**Created:** [September 5, 2006, 8:46pm UTC](https://www.ruby-forum.com/t/modifying-the-first-value-with-inject/67634 "2006-09-05T20:46:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 5, 2006, 8:46pm UTC](https://www.ruby-forum.com/t/modifying-the-first-value-with-inject/67634/1 "2006-09-05T20:46:19Z")

</div>

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 }  
end  
def running\_divide  
inject{ |total, entry| total / entry.to\_f }  
end  
end

a1 = [5,4,3,2,1]  
p a1.sum  
#=\> 15.0  
p a1.product  
#=\> 120.0  
p a1.running\_difference  
#=\> -5.0  
p a1.running\_divide  
#=\> 0.208333333333333

a2 = [“5”,“4”,“3”,“2”,“1”]  
p a2.sum  
#=\> 15.0  
p a2.product  
#=\> 120.0  
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

---

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 5, 2006, 9:36pm UTC](https://www.ruby-forum.com/t/modifying-the-first-value-with-inject/67634/2 "2006-09-05T21:36:26Z")

</div>

On 9/5/06, Phrogz [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 5, 2006, 11:26pm UTC](https://www.ruby-forum.com/t/modifying-the-first-value-with-inject/67634/3 "2006-09-05T23:26:38Z")

</div>

Phrogz wrote:

> def running\_difference  
> inject{ |total, entry| total - entry.to\_f }  
> end  
> def running\_divide  
> inject{ |total, entry| total / entry.to\_f }  
> end  
> end

Personally I would definitively not include those .to\_f’s because those  
make the code less useful. Consider for example an array that contains  
Bignums - you force them to floats and get imprecise float match as  
opposed to precise int math. Let #coerce() do it’s work.

Also, Enumerable seems a better place for such general methods.

> a2 = [“5”,“4”,“3”,“2”,“1”]  
> p a2.sum  
> #=\> 15.0  
> p a2.product  
> #=\> 120.0  
> 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

IMHO the map or map! approach is better because you get better  
modularization. If you want the performance you can use inject directly

- but for those general methods I would not have these conversions.

Oh, wait, you could do this:

module Enumerable  
def sum(\*init,&b)  
b ||= lambda {|x| x}  
inject(\*init) {|x,y| x + b[y]}  
end  
end

irb(main):010:0\> %w{1 2 3 4}.sum(0) {|x| x.to\_i}  
=\> 10  
irb(main):011:0\> %w{1 2 3 4}.sum  
=\> “1234”

Or even

module Enumerable  
def agg(op,\*init,&b)  
b ||= lambda {|x| x}  
inject(\*init) {|x,y| x.send(op, b[y])}  
end  
end

irb(main):019:0\* %w{1 2 3 4}.agg(:\*, 1) {|x| x.to\_i}  
=\> 24  
irb(main):020:0\> %w{1 2 3 4}.agg(:+, 0) {|x| x.to\_i}  
=\> 10  
irb(main):022:0\> %w{1 2 3 4}.agg(:+)  
=\> “1234”

Kind regards

```
robert
```
