Creating 2-D array from 1-D array

Hello, I am relatively new to Ruby. I have an existing array:
a = [1 , 2 , 3 , 4 , 5 , 6]
and I want to create this 2-D array:
b = [[1 , 2][2 , 4][5 , 6]]
I am using the following code, which works, but seems somewhat clumsy:
b = Array.new
i = 0
k = 0
for item in a
if i == 0
a1 = item
i = 1
elsif i == 1
a2 = item
i = 0
b[k] = [a1, a2]
puts “b…#{k}, #{b[k]}”
k = k + 1
end
end
I would appreciate any advice to make this code look more elegant or
ruby-like. In particular, I suspect there is a way to avoid the
indices.
Thanks for the help.

Here are some suggestions, which should help reduce the use of indices
and local variables.

When constructing the array b, you don’t need to reference a position.
You can start with an empty array, and push the new pairs onto the end:

instead of b = Array.new, write b = []
instead of b[k] = [a1, a2], write b << [a1, a2]

That gets rid of k.

To get the pairs, I suggest you investigate ‘slice’.

e.g. a.slice(0, 2) returns a two-element array from the 0th position of
a: [1, 2]

You will also need to change your looping mechanism if you use slice,
but you should be able to get rid of a1 and a2.

Thanks a lot for the suggestions.
I also found a good tip at:

Now my code looks like:
a = [1 , 2 , 3 , 4 , 5 , 6]
b = []
(0…a.length-1).step(2) do |i|
b << [a[i], a[i+1]]
end
print b
There might also be a simple solution using slice, need to work on it.
Much better! Thanks again

You can also use Hash constructor:

a = [1 , 2 , 3 , 4 , 5 , 6]
siliced = Hash[*a].to_a

Sandro

On Sun, Nov 27, 2011 at 7:06 AM, J. Marshal [email protected] wrote:

   a1 = item

ruby-like. In particular, I suspect there is a way to avoid the
indices.
Thanks for the help.


Posted via http://www.ruby-forum.com/.

There are some very helpful methods in Enumerable

(http://rubydoc.info/stdlib/core/1.9.3/Enumerable).

In this case, check out each_slice.

ary = [1 , 2 , 3 , 4 , 5 , 6]
sliced = ary.each_slice 2

sliced # => #<Enumerator: [1, 2, 3, 4, 5, 6]:each_slice(2)>

You can think of it like the array you showed,

for instance you can iterate over its elements

or map them to new values or whatever.

sliced.each do |element|
element # => [1, 2], [3, 4], [5, 6]
end

sliced.map(&:reverse) # => [[2, 1], [4, 3], [6, 5]]

But if you really need an array, you can get it with to_a

sliced.to_a # => [[1, 2], [3, 4], [5, 6]]

Many thanks for the tips. You guys are great!

On Sun, Nov 27, 2011 at 4:50 PM, Sandro P.
[email protected] wrote:

You can also use Hash constructor:

a = [1 , 2 , 3 , 4 , 5 , 6]
siliced = Hash[*a].to_a

Beware that this will only work if the odd elements are unique.

Hash[*[1,2,1,3,1,4]].to_a
=> [[1, 4]]