Each with previous?

I'm going through lots of data where the result of the current is affected by the previous element. So what I would need is an
"each_with_previous {|current, prev|}"
...to make it a bit more readable. Is there any built-in Ruby method that I might have overlooked, or should I build my own?

Best regards,

Jari Williamsson

Enumerable.each_cons(2) { |current, prev| ... }

Eivind.

···

On Dec 14, 2007 4:28 PM, Jari Williamsson <jari.williamsson@mailbox.swipnet.se> wrote:

I'm going through lots of data where the result of the current is
affected by the previous element. So what I would need is an
"each_with_previous {|current, prev|}"
...to make it a bit more readable. Is there any built-in Ruby method
that I might have overlooked, or should I build my own?

I'm going through lots of data where the result of the current is affected
by the previous element. So what I would need is an
"each_with_previous {|current, prev|}"
...to make it a bit more readable. Is there any built-in Ruby method that I
might have overlooked, or should I build my own?

You can fake it pretty simply with inject. For example:

[ 1,2,3,4,5 ].inject { |prev,cur| puts "#{prev}, #{cur}"; cur }

1, 2
2, 3
3, 4
4, 5

Note that you do need the block to "return" (i.e. evaluate to) the current
element so that it gets passed into the next iteration.

Best regards,
Jari Williamsson

--Greg

···

On Sat, Dec 15, 2007 at 12:28:51AM +0900, Jari Williamsson wrote:

require 'enumerator'

[first, second, third].each_slice(2) do |prev,curr|
   # do stuff
end

Except that you don't get a [nil,first] pair to start, you get [first,second].

You could also do something like:

[first, second, third].inject(nil) do |prev, curr|
   # do stuff
   curr
end

And curr is assigned to prev in the next iteration and the first iteration gets [nil,first]

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

···

On Dec 14, 2007, at 10:28 AM, Jari Williamsson wrote:

I'm going through lots of data where the result of the current is affected by the previous element. So what I would need is an
"each_with_previous {|current, prev|}"
...to make it a bit more readable. Is there any built-in Ruby method that I might have overlooked, or should I build my own?

Best regards,

Jari Williamsson

Take your pick:

irb(main):001:0> a = %w| a b c d e f g h |
=> ["a", "b", "c", "d", "e", "f", "g", "h"]

irb(main):002:0> require 'enumerator'

irb(main):003:0> a.each_cons(2){ |x,y| puts "#{x}-#{y}" }
a-b
b-c
c-d
d-e
e-f
f-g
g-h

irb(main):004:0> a.each_slice(2){ |x,y| puts "#{x}-#{y}" }
a-b
c-d
e-f
g-h

···

On Dec 14, 8:28 am, Jari Williamsson <jari.williams...@mailbox.swipnet.se> wrote:

I'm going through lots of data where the result of the current is
affected by the previous element. So what I would need is an
"each_with_previous {|current, prev|}"
..to make it a bit more readable. Is there any built-in Ruby method
that I might have overlooked, or should I build my own?

There is a subtlety: with your code there will be no previous for the first element. Depending on what the OP needs you can as well do

irb(main):001:0> (1..5).inject(nil) {|prev,curr| p [prev,curr];curr}
[nil, 1]
[1, 2]
[2, 3]
[3, 4]
[4, 5]
=> 5

Jari, what kind of calculation do you do?

Cheers

  robert

···

On 14.12.2007 16:39, Gregory Seidman wrote:

On Sat, Dec 15, 2007 at 12:28:51AM +0900, Jari Williamsson wrote:

I'm going through lots of data where the result of the current is affected by the previous element. So what I would need is an
"each_with_previous {|current, prev|}"
...to make it a bit more readable. Is there any built-in Ruby method that I might have overlooked, or should I build my own?

You can fake it pretty simply with inject. For example:

[ 1,2,3,4,5 ].inject { |prev,cur| puts "#{prev}, #{cur}"; cur }

1, 2
2, 3
3, 4
4, 5

Note that you do need the block to "return" (i.e. evaluate to) the current
element so that it gets passed into the next iteration.

Robert Klemme wrote:

There is a subtlety: with your code there will be no previous for the first element. Depending on what the OP needs you can as well do

irb(main):001:0> (1..5).inject(nil) {|prev,curr| p [prev,curr];curr}
[nil, 1]
[1, 2]
[2, 3]
[3, 4]
[4, 5]
=> 5

Jari, what kind of calculation do you do?

I'll use different approaches for different situations. Starting inject with nil or first item will both become handy. Thanks!

The tasks are for analyzing musical data. The current note is most often dependent of previous context.

Best regards,

Jari Williamsson