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
Hi –
On Wed, 8 Aug 2007, FireAphis wrote:
45
[1,2,3,4,5].inject {|a,b| puts “#{a}#{b}”; b }
David
FireAphis wrote:
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 
On 8/8/07, FireAphis [email protected] wrote:
45
FireAphis
Enumerable#each_slice(n) {|…| …}
On 8/8/07, Jano S. [email protected] wrote:
34
Thanks
FireAphis
Enumerable#each_slice(n) {|…| …}
Sorry Enumerable#each_cons(n) { }
you might need to require ‘enumerable’ though.
require ‘labrador/enum’
a.zip(a.map.succ).map.join.first(-1)
but the version with first is not released yet 
Robert
Hi –
On Wed, 8 Aug 2007, Jano S. wrote:
34
Thanks
FireAphis
Enumerable#each_slice(n) {|…| …}
That won’t work because it won’t double back; you’ll get 12, 34, 5
instead of 12, 23, 34, 45.
However, you reminded me of something:
require ‘enumerator’
[1,2,3,4,5].enum_cons(2).each {|a,b| puts “#{a}#{b}” }
David
Hi –
On Wed, 8 Aug 2007, Robert D. wrote:
require ‘labrador/enum’
a.zip(a.map.succ).map.join.first(-1)
but the version with first is not released yet 
I can’t quite follow how that will get to the result. Can you walk me
through it? My first reaction is that it’s awfully full of “magic
dots”, but I’m willing to be enlightened…
(And I honestly
can’t puzzle it out.)
David
On 8/8/07, [email protected] [email protected] wrote:
Hi –
On Wed, 8 Aug 2007, Robert D. 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
On Aug 8, 4:43 pm, [email protected] wrote:
12
RAILS ROUTING (new!http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (Ruby for Rails)
Short and elegant!
On Aug 8, 5:35 pm, “Robert D.” [email protected] wrote:
and the method name, thus
end
–
[…] as simple as possible, but no simpler.
– Attributed to Albert Einstein
Thanks everybody for help and plethora of solution ideas you’ve been
very helpful.
Thanks again
FireAphis
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.wordpress.com/.
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]]