Another of those trivial little problems that I obsess about finding
the Proper way to do - what’s a nice, idiomatic Ruby way to go from
[a,b,c,d…] to [[a,b],[c,d],[e,f],…]? Note that I want to
preserve the ordering, so to_hash won’t work.
One way I thought of was
b = []
while a[0] do
b << [a.shift, a.shift]
end
which works but doesn’t look particularly elegant.
martin
martindemello@yahoo.com (Martin DeMello) writes:
Another of those trivial little problems that I obsess about finding
the Proper way to do - what’s a nice, idiomatic Ruby way to go from
[a,b,c,d…] to [[a,b],[c,d],[e,f],…]? Note that I want to
preserve the ordering, so to_hash won’t work.
One way I thought of was
b =
while a[0] do
b << [a.shift, a.shift]
end
This isn’t much better, but
b = []
b << a.slice!(0,2) until a.empty?
Cheers
Dave
I ran into the same requirement and I solved it by extending the Array
class. Have a look…
class Array
···
#---------------------------------------------------------------------
# each_group
#---------------------------------------------------------------------
def each_group ( sizeof )
limitOf = length-1
0.step( limitOf, sizeof ) { |i| yield( self[i,sizeof] ) }
end
#---------------------------------------------------------------------
# collect_each_group
#---------------------------------------------------------------------
def collect_each_group ( sizeof )
rtn = []
limitOf = length-1
0.step( limitOf, sizeof ) { |i| rtn << yield( self[i,sizeof] ) }
rtn
end
end
a = [ 1,2,3,4,5,6,7,8,9,10 ]
b = a.collect_each_group(2) { |items| items }
and b = [[1,2],[3,4],[5,6],[7,8],[9,10]]
Hope it helps…
-----Original Message-----
From: Martin DeMello [mailto:martindemello@yahoo.com]
Sent: October 20, 2002 19:52
To: ruby-talk ML
Subject: Grouping by twos
Another of those trivial little problems that I obsess about finding
the Proper way to do - what’s a nice, idiomatic Ruby way to go from
[a,b,c,d…] to [[a,b],[c,d],[e,f],…]? Note that I want to
preserve the ordering, so to_hash won’t work.
One way I thought of was
b = []
while a[0] do
b << [a.shift, a.shift]
end
which works but doesn’t look particularly elegant.
martin
“Allen Mitchell” ajm@nb.sympatico.ca wrote in message news:MHEFIIKIPJCFBKBGMHOGEEPPCOAA.ajm@nb.sympatico.ca…
I ran into the same requirement and I solved it by extending the Array
class. Have a look…
Neat. Getting positively verbose, but here’s an extension to Enumerable
module Enumerable
def eachn(n)
a =
if block_given?
each {|i|
a << i
if a.length == n
yield a
a =
end
}
yield a unless a.empty? #possibly padded with nils
else
b =
eachn(n) {|i| b << i}
b
end
end
end
a = (1…10).to_a
b = a.eachn(2)
puts a.inspect, # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b.inspect # => [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
But the method name is short and expressive. I like that. 
Hm, from `eachn’ I’d expect:
a.eachn(2) do |x, y|
…
end
a.eachn(3) do |x, y, z|
…
end
I’d rewrite `b = a.eachn(2)’ in:
b = a.collectn(2) {|a, b| [a, b]}
For which an optional blockless form would make sense:
b = a.collectn(2)
Massimiliano
···
On Tue, Oct 22, 2002 at 05:34:47AM +0900, Martin DeMello wrote:
Neat. Getting positively verbose,