要望
今手元にある一次元配列を、要素a個のN次元配列(多次元配列)に変換したい。
初期化の方法ではなく、すでに存在する配列をどうこうする。
理解の方針
今回は、まず2次元と3次元を取り扱い、多次元配列の理解を深める。
その後、帰納的にN+1次元を実現する。
N次元配列について
まずN次元配列についての理解を深める。
1次元配列
数直線を考えるとわかりやすい。
[1, 2, 3, ...]
2次元配列
X軸とY軸を考えるとわかりやすい。
2次元目の要素数は実は何個でもいい。
[ [1, 2], [3, 4, 5], [6], ... ]
3次元配列
番地を想像するとわかりやすい。
[ # 0番目 [ # 0-1 [ 1, # 0-1-0 2 # 0-1-1 ], # 0-1 [ 3 # 0-1-0 ] ], # 1番目 [ [ 3, 4, 5], [6], ] ... ]
まとめると
- some_array[x][y]でアクセスできるなら、2次元配列列。
- some_array[x][y][z]でアクセスできるなら、3次元配列。
みために惑わされがち。
つぎにコードを書いていく。
2次元配列の場合
コード
p [1,2,3,4,5].each_slice(2).to_a
ワンライナーでチェック
ruby -e 'p [1,2,3,4,5].each_slice(2).to_a'
結果
[[1, 2], [3, 4], [5]]
each_sliceの使い方
3次元配列の場合
何個かの要素に分けたいので、elm_count
に要素数を入れる
some_array[x][y][z]でアクセスできるなら、3次元配列。
yとzの個数の上限を設ける必要がある。
yの個数を2個、 zの個数を2個にした場合のイメージ
[ [ [1, 2], [3, 4] ], [ [5, 6], [7, 8] ] ],
ruby -e ' max_elm_in_second_floor = 2 max_elm_in_third_floor = 2 array = [1, 2, 3, 4, 5, 6, 7, 8] new_array = array.each_slice(max_elm_in_second_floor).each_slice(max_elm_in_third_floor).to_a p new_array'
まとめ
N次元配列つくるときは、各階層の要素数を決める。
汎化すると、
def to_multidimensional(array, dimension, *each_floor_element) return array if each_floor_element.empty? sub_array_size = each_floor_element.reduce(:*) || 1 array.each_slice(sub_array_size).map { |sub| to_multidimensional(sub, *each_floor_element) } end # 使用例 one_d_array = (1..8).to_a dimension = 3 each_floor_element = [2, 2] # 次元数 three_d_array = to_multidimensional(one_d_array, dimension, *each_floor_element) p three_d_array