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.
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
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
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 
On 4/9/07, Jason M. [email protected] 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/
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