Creating an array of differences

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.

···

--
Posted via http://www.ruby-forum.com/.

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 Gray II

···

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

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

···

On 09.04.2007 15:46, Jason Madigan 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.

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.

···

On 4/9/07, Jason Madigan <nuphor@gmail.com> 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.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

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

Jason Madigan 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.

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 :slight_smile:

···

--
Posted via http://www.ruby-forum.com/.