Ruby Multidimensional Array

Ruby multidimensional array

Strictly speaking it is not possible to create multi dimensional arrays in Ruby. But it is possible to put an array in another array, which is almost the same as a multi dimensional array.

This is how you could create a 2D array in Ruby:

a = [[1,2,3], [4,5,6], [7,8,9]]



As stated in the comments, you could also use NArray which is a Ruby numerical array library:

require 'narray'
b = NArray[ [1,2,3], [4,5,6], [7,8,9] ]

Use a[i][j] to access the elements of the array. Basically a[i] returns the 'sub array' stored on position i of a and thus a[i][j] returns element number j from the array that is stored on position i.

ruby convert multidimensional array into one array

You could do something like this:

arr = [[["/path/element1", false], 7], [[4, true], 5], [["/path/element6", false], 1]]
arr.map { |k,v| [*k,v] }
#=> [["/path/element1", false, 7], [4, true, 5], ["/path/element6", false, 1]]

How to convert multidimensional array into a 2 dimensional array?

also, next time you can try to read documentation :)

a = [[[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5]], [[1, 0], [1, 1], [1, 2],   [1, 3], [1, 4], [1, 5]], [[2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5]], [[3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [3, 5]], [[4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5]], [[5, 0], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5]]]

a.flatten(1)
>[[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [3, 5], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [5, 0], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5]]

Ruby: multidimensional array to one-dimensional rows

I needed a more generic and flexible solution as compared to the ones proposed (my bad, I should have been more clear about the requirements), so I came up with the following:

class Array
def transpose_rows
arys = self.select{|el| el.is_a?(Array)}
if arys.size == 0
[self]
else
result = []
(arys.map(&:size).max || 1).times.map{ |i|
self.map { |r|
r.is_a?(Array) ? r[i] : r
}.transpose_rows.map{|r| result << r}
}
result
end
end
end

The initial spec is that every element in the array is either a value or another array of varying depth. Each subarray "explodes" the values of the subarrays of depth-1 into an arbitrary number of "sub-values". The result should be a set of rows listing all combinations deriving from the original array.

The other solutions proposed do work for the original array I posted, which was just an example, while this one works for more complex scenarios such as the following:

[
2,
[3,4,5],
6,
[7,8,9],
[ [11,22], [33], [44,55] ],
[0, 1, 2],
[ [66], [77], [nil,99] ],
4
].transpose_rows

# => [
# [2, 3, 6, 7, 11, 0, 66, 4],
# [2, 3, 6, 7, 22, 0, nil, 4],
# [2, 4, 6, 8, 33, 1, 77, 4],
# [2, 5, 6, 9, 44, 2, nil, 4],
# [2, 5, 6, 9, 55, 2, 99, 4]
# ]

How to sort a two-dimensional array (2d array) by date in ruby on rails?

You can sort 2d arrays with sort_by method: sort_by sorts in ascending order by default. If you want it to be in descending order, just reverse the result.

array.sort_by{ |a| a.first }.reverse

Find index of array in multidimensional array by string value

That's returning nil, because there's no element i (index) in the array with value #FFF600 (nor FFF600), you need to access to the hex_value key value:

p [
{:id=>5, :name=>"Leaf Green", :hex_value=>"047115"},
{:id=>15, :name=>"Lemon Yellow", :hex_value=>"FFF600"},
{:id=>16, :name=>"Navy", :hex_value=>"285974"}
].yield_self { |this| this.each_index.select { |index| this[index][:hex_value] == 'FFF600' } }
# [1]

Giving you [1], because of using select, if you want just the first occurrence, you can use find instead.

I'm using yield_self there, to avoid assigning the array to a variable. Which is equivalent to:

array = [
{:id=>5, :name=>"Leaf Green", :hex_value=>"047115"},
{:id=>15, :name=>"Lemon Yellow", :hex_value=>"FFF600"},
{:id=>16, :name=>"Navy", :hex_value=>"285974"}
]
p array.each_index.select { |index| array[index][:hex_value] == 'FFF600' }
# [1]

Being Ruby, you can use the method for that: Enumerable#find_index

p [
{:id=>5, :name=>"Leaf Green", :hex_value=>"047115"},
{:id=>15, :name=>"Lemon Yellow", :hex_value=>"FFF600"},
{:id=>16, :name=>"Navy", :hex_value=>"285974"}
].find_index { |hash| hash[:hex_value] == 'FFF600' }
# 1

Ruby - Sort multidimensional array by first line

You can use Array#transpose and Enumerable#sort_by to handle this like so:

 arr = [ [ "A 1", "A 3", "A 2", "A 4" ],
[ 4, 5, 6, 7 ],
[ 2, 2, 2, 2 ],
[ 0.1, 0.2, 0.1, 0.2 ] ]

Array#transpose turns rows into columns:

arr.transpose
#=> [["A 1", 4, 2, 0.1],
# ["A 3", 5, 2, 0.2],
# ["A 2", 6, 2, 0.1],
# ["A 4", 7, 2, 0.2]]

Then we just need to sort by the first column values sort_by(&:first):

arr.transpose.sort_by(&:first)
#=> [["A 1", 4, 2, 0.1],
# ["A 2", 6, 2, 0.1],
# ["A 3", 5, 2, 0.2],
# ["A 4", 7, 2, 0.2]]

Then we just transpose back again:

arr.transpose.sort_by(&:first).transpose
#=> [["A 1", "A 2", "A 3", "A 4"],
# [4, 6, 5, 7],
# [2, 2, 2, 2],
# [0.1, 0.1, 0.2, 0.2]]

The same could be achieved by zipping the Arrays together like so: (but the former seems like a better choice)

arr.reduce(&:zip).sort_by {|a| a.flatten!.first}.transpose
#=> [["A 1", "A 2", "A 3", "A 4"],
# [4, 6, 5, 7],
# [2, 2, 2, 2],
# [0.1, 0.1, 0.2, 0.2]]


Related Topics



Leave a reply



Submit