[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Iterating list in pairs

FireAphis@gmail.com

8/8/2007 1:40:00 PM

Hello,

I need to iterate through a list and handle two elements on every
iteration. That is I'd like to do something like

[1,2,3,4,5].each { |x, y| puts x.to_s + y.to_s }

12
23
34
45

This code doesn't work off course.
I can iterate using indices

0.upto(list.size-1) { |i| puts list[i] + list[i+1] }

But it looks ugly to me. Do you know any elegant tricks that don't use
list indices?

Thanks
FireAphis

12 Answers

David A. Black

8/8/2007 1:43:00 PM

0

Alex Young

8/8/2007 1:44:00 PM

0

FireAphis wrote:
> Hello,
>
> I need to iterate through a list and handle two elements on every
> iteration. That is I'd like to do something like
>
> [1,2,3,4,5].each { |x, y| puts x.to_s + y.to_s }
>
> 12
> 23
> 34
> 45
>
> This code doesn't work off course.
> I can iterate using indices
>
> 0.upto(list.size-1) { |i| puts list[i] + list[i+1] }
>
> But it looks ugly to me. Do you know any elegant tricks that don't use
> list indices?
irb(main):001:0> a = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):002:0> a[0,4].zip(a[1,5]).each{|x,y| puts x.to_s + y.to_s}
12
23
34
45
=> [[1, 2], [2, 3], [3, 4], [4, 5]]

Unless a[0,4] breaks your "no list indices" rule, of course :-)

--
Alex

Jano Svitok

8/8/2007 1:45:00 PM

0

On 8/8/07, FireAphis <FireAphis@gmail.com> wrote:
> Hello,
>
> I need to iterate through a list and handle two elements on every
> iteration. That is I'd like to do something like
>
> [1,2,3,4,5].each { |x, y| puts x.to_s + y.to_s }
>
> 12
> 23
> 34
> 45
>
> This code doesn't work off course.
> I can iterate using indices
>
> 0.upto(list.size-1) { |i| puts list[i] + list[i+1] }
>
> But it looks ugly to me. Do you know any elegant tricks that don't use
> list indices?
>
> Thanks
> FireAphis

Enumerable#each_slice(n) {|...| ...}

Alex Young

8/8/2007 1:47:00 PM

0

dblack@rubypal.com wrote:
> Hi --
>
> On Wed, 8 Aug 2007, FireAphis wrote:
>
>> Hello,
>>
>> I need to iterate through a list and handle two elements on every
>> iteration. That is I'd like to do something like
>>
>> [1,2,3,4,5].each { |x, y| puts x.to_s + y.to_s }
>>
>> 12
>> 23
>> 34
>> 45
>
> [1,2,3,4,5].inject {|a,b| puts "#{a}#{b}"; b }
>
Oh, that's neat :-)

--
Alex

Jano Svitok

8/8/2007 1:47:00 PM

0

On 8/8/07, Jano Svitok <jan.svitok@gmail.com> wrote:
> On 8/8/07, FireAphis <FireAphis@gmail.com> wrote:
> > Hello,
> >
> > I need to iterate through a list and handle two elements on every
> > iteration. That is I'd like to do something like
> >
> > [1,2,3,4,5].each { |x, y| puts x.to_s + y.to_s }
> >
> > 12
> > 23
> > 34
> > 45
> >
> > This code doesn't work off course.
> > I can iterate using indices
> >
> > 0.upto(list.size-1) { |i| puts list[i] + list[i+1] }
> >
> > But it looks ugly to me. Do you know any elegant tricks that don't use
> > list indices?
> >
> > Thanks
> > FireAphis
>
> Enumerable#each_slice(n) {|...| ...}
>

Sorry Enumerable#each_cons(n) { }

you might need to require 'enumerable' though.

David A. Black

8/8/2007 1:50:00 PM

0

Robert Dober

8/8/2007 2:05:00 PM

0

require 'labrador/enum'
a.zip(a.map.succ).map.join.first(-1)

but the version with first is not released yet :(

Robert

--
[...] as simple as possible, but no simpler.
-- Attributed to Albert Einstein

David A. Black

8/8/2007 2:17:00 PM

0

Robert Dober

8/8/2007 2:36:00 PM

0

On 8/8/07, dblack@rubypal.com <dblack@rubypal.com> wrote:
> Hi --
>
> On Wed, 8 Aug 2007, Robert Dober wrote:
>
> > require 'labrador/enum'
> > a.zip(a.map.succ).map.join.first(-1)
map without a parameter creates a Proxy object that contains the
enumeration and the method name :map.
It's method_missing forwards everything to the enumeration via send
and the method name, thus
map.join becomes
map{|x| x.send(:join)}

it is not everybody's cup of tea, but I love it, obviously.
Labrador, the LAZY programmers best friend ;)

class EmptyProxy < EmptyObject
def initialize object, message
@enum = object
@message = message
end
end

class Dispatcher < EmptyProxy
def method_missing mth, *args, &blk
@enum.send(@message){|x| x.send(mth.to_sym,*args)}
end # def method_missing mth, *args, &blk
end # class Dispatcher < EmptyProxy

Cheers
Robert


--
[...] as simple as possible, but no simpler.
-- Attributed to Albert Einstein

Drew Olson

8/8/2007 7:05:00 PM

0

FireAphis wrote:
> Hello,
>
> I need to iterate through a list and handle two elements on every
> iteration. That is I'd like to do something like

Weird, I just blogged about this topic: http://drewolson.word....

I did it using the zip method, something like this (I added block
handling to this example):

class Array
def adjacent_pairs
if block_given?
self[0..-2].zip(self[1..-1]).each do |a,b|
yield a,b
end
else
self[0..-2].zip(self[1..-1])
end
end
end

Now we can do either of the following:

irb(main):012:0> [1,2,3,4].adjacent_pairs
=> [[1, 2], [2, 3], [3, 4]]
irb(main):013:0> [1,2,3,4].adjacent_pairs do |a,b|
irb(main):014:1* puts "#{a} #{b}"
irb(main):015:1> end
1 2
2 3
3 4
=> [[1, 2], [2, 3], [3, 4]]
--
Posted via http://www.ruby-....