最近のPRのレビューをしているときに、二次元配列のデータを入れ替える処理をしているところがあったので、レビュー後にチャットで意見交換していたら綺麗な感じにできたのでそれをメモして残しておく。
transpose
を使うのがミソなのだけれど、transpose
を使うには、配列の要素数を統一しなければならない。そのために、values_at
を使う。このvalues_at
を使うアイデアはパートナーさんが考えてくれた。
# 要素数が異なる配列を準備… arr = [['a', 'b'], ['c', 'd', 'e', 'f'], [], ['g', 'h', 'i']] # その中から最大要素数を取得 max_size = arr.map(&:size).max # 各配列の要素数を最大要素数に合わせる arr.map! {|it| it.values_at(0...max_size) } # 行と列を入れ替える arr.transpose # => [ # ["a", "c", nil, "g"], # ["b", "d", nil, "h"], # [nil, "e", nil, "i"], # [nil, "f", nil, nil]]
最初はzip
を使おうとしていたのだが、zip
を使う場合は先頭要素に最も大きな配列がなければうまくいかないということを指摘してもらって、別のアイデアを考えていたら、こうなった。
縦持ちと横持ちのデータの入れ替えは時々したくなることがあるので、いざと言う時にこの記事を思い出したい。