# Creating an array of differences

**URL:** <https://www.ruby-forum.com/t/creating-an-array-of-differences/91468>\
**Category:** Ruby\
**Created:** [April 9, 2007, 3:46pm UTC](https://www.ruby-forum.com/t/creating-an-array-of-differences/91468 "2007-04-09T15:46:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [April 9, 2007, 3:46pm UTC](https://www.ruby-forum.com/t/creating-an-array-of-differences/91468/1 "2007-04-09T15:46:42Z")

</div>

Hey there,

I’m pretty new to Ruby so perhaps some of you could help me out with a  
little problem I’ve come up against. I have an array consisting of  
integers (called session[:octets\_in]). What I want to do is create an  
array comprising of the difference between the current element and the  
previous element (e.g. [“1000”, “1100”, “1200”] would become [“100”,  
“200”]). I’m not entirely sure how to go about this, so any pointers  
would be welcome.

---

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [April 9, 2007, 4:17pm UTC](https://www.ruby-forum.com/t/creating-an-array-of-differences/91468/2 "2007-04-09T16:17:59Z")

</div>

On Apr 9, 2007, at 8:46 AM, Jason M. wrote:

> Hey there,

Hello.

> I’m pretty new to Ruby so perhaps some of you could help me out with a  
> little problem I’ve come up against.

Sure. Welcome to Ruby.

> I have an array consisting of  
> integers (called session[:octets\_in]). What I want to do is create an  
> array comprising of the difference between the current element and the  
> previous element (e.g. [“1000”, “1100”, “1200”] would become [“100”,  
> “200”]).

Hmm, your description and your example don’t say the same thing.  
I’ll assume you meant the answer should be [“100”, “100”].

> I’m not entirely sure how to go about this, so any pointers  
> would be welcome.

With just core Ruby you could do:

> > data = %w[1000 1100 1200]  
> > =\> [“1000”, “1100”, “1200”]
> 
> > (1…(data.size - 1)).inject(Array.new) do |diffs, i|  
> > ?\> diffs + [(data[i - 1].to\_i - data[i].to\_i).abs.to\_s]
> 
> > end  
> > =\> [“100”, “100”]

However, I think it looks a little prettier if you load a standard  
library and solve it like this:

> > require “enumerator”  
> > =\> true
> 
> > data.enum\_cons(2).map { |l, r| (l.to\_i - r.to\_i).abs.to\_s }  
> > =\> [“100”, “100”]

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [April 9, 2007, 4:20pm UTC](https://www.ruby-forum.com/t/creating-an-array-of-differences/91468/3 "2007-04-09T16:20:59Z")

</div>

On 09.04.2007 15:46, Jason M. wrote:

> I’m pretty new to Ruby so perhaps some of you could help me out with a  
> little problem I’ve come up against. I have an array consisting of  
> integers (called session[:octets\_in]). What I want to do is create an  
> array comprising of the difference between the current element and the  
> previous element (e.g. [“1000”, “1100”, “1200”] would become [“100”,  
> “200”]). I’m not entirely sure how to go about this, so any pointers  
> would be welcome.

I think you would get [100,100] in your case (apart from the fact that  
the array you present is an array of strings).

I think the most elegant solution is with #each\_cons; with enumerator  
you can do:

irb(main):007:0\> (1…10).to\_enum(:each\_cons, 2).map {|a,b| b-a}  
=\> [1, 1, 1, 1, 1, 1, 1, 1, 1]

irb(main):008:0\> [1000,1100,1200].to\_enum(:each\_cons, 2).map {|a,b| b-a}  
=\> [100, 100]

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [April 9, 2007, 4:48pm UTC](https://www.ruby-forum.com/t/creating-an-array-of-differences/91468/4 "2007-04-09T16:48:03Z")

</div>

All,

Thank you very much for all your replies, they’re incredibly helpful!  
And apologies for my mistake in the original post, I of course meant  
[“100”, “100”]. You’ve all given me plenty of food for thought 🙂

---

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [April 9, 2007, 4:40pm UTC](https://www.ruby-forum.com/t/creating-an-array-of-differences/91468/5 "2007-04-09T16:40:02Z")

</div>

On 4/9/07, Jason M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hey there,
> 
> I’m pretty new to Ruby so perhaps some of you could help me out with a  
> little problem I’ve come up against. I have an array consisting of  
> integers (called session[:octets\_in]). What I want to do is create an  
> array comprising of the difference between the current element and the  
> previous element (e.g. [“1000”, “1100”, “1200”] would become [“100”,  
> “200”]). I’m not entirely sure how to go about this, so any pointers  
> would be welcome.

Did you really mean that this would produce [“100”, “100”]? since the  
element before “1200” is “1100” not “1000”.

require ‘enumerator’

[“1000”, “1100”, “1200”, “1420”].enum\_for(:each\_cons, 2).map {|a, b|  
(b.to\_i - a.to\_i).to\_s} =\> [“100”, “100”, “220”]

If you really meant the difference between the second and subsequent  
elements and the first, then here’s a tricksy way to to it:

[“1000”, “1100”, “1200”].inject(nil) {|s,e| s ? s \<\< (e.to\_i -  
s.first.to\_i).to\_s : [e]}[1…-1]

## It stores the first element in the ‘sum’ being computed by inject, then strips it off.

Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![jasonmorrison](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/47e85d/32.png) [@jasonmorrison](https://www.ruby-forum.com/u/jasonmorrison)\
**Post date:** [April 9, 2007, 7:01pm UTC](https://www.ruby-forum.com/t/creating-an-array-of-differences/91468/6 "2007-04-09T19:01:17Z")

</div>

Here’s another way of doing it:

(a.zip(a[1…a.length])[0…a.length-1]).map { |a,b| b-a }

This things makes an array of pairs of the elements:

irb(main):007:0\> a = [1000, 1100, 1200]  
=\> [1000, 1100, 1200]  
irb(main):029:0\> a.zip(a[1…a.length])[0…a.length-1]  
=\> [[1000, 1100], [1100, 1200]]  
irb(main):030:0\> (a.zip(a[1…a.length])[0…a.length-1]).map { |a,b| b-a  
}  
=\> [100, 100]

-Reuben
