[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

each with previous?

Jari Williamsson

12/14/2007 3:29:00 PM

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

6 Answers

Eivind Eklund

12/14/2007 3:39:00 PM

0

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?

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

Eivind.

Gregory Seidman

12/14/2007 3:40:00 PM

0

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.

> Best regards,
> Jari Williamsson
--Greg


Rob Biedenharn

12/14/2007 3:45:00 PM

0

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


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://agileconsult...
Rob@AgileConsultingLLC.com



Phrogz

12/14/2007 4:12:00 PM

0

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?

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

Robert Klemme

12/14/2007 6:00:00 PM

0

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.

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

Jari Williamsson

12/14/2007 11:58:00 PM

0

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