Rubyでは多次元配列やハッシュを一次元配列に変換するための「flatten」メソッドが提供されています。
本記事では、flattenメソッドの使い方について初心者向けにサンプルコードを交えながらご紹介していきます。
目次
flattenメソッドとは
flattenメソッドは、Rubyの組み込みライブラリに含まれる「Array」クラスと「Hash」クラスより提供されているメソッドです。
「自身を再帰的に平坦化した配列を生成して返す」と公式ドキュメントで表現されているように、多次元配列やハッシュを一次元配列として返却することが出来る機能を提供しています。
利用用途
flattenメソッドは、ニューラルネットワークなどの実装を行う際に利用されるメソッドです。
Web開発でRubyを利用されている方の場合、それほど利用機会の多いメソッドではないでしょう。
flattenメソッドの記述法
多次元配列やハッシュのオブジェクトにflattenを下記のように記述して一次元配列を取得します。
オブジェクト.flattern または オブジェクト.flatten(階層レベル)
flattenメソッドには階層レベルを整数で指定することが可能で、指定した値に応じて展開する階層の深さを決定します。
多次元配列を一次元配列に変換するサンプル
多次元配列を一次元配列に変換するサンプルコードから確認していきましょう。
引数指定なし
flattenメソッドに引数を指定しない場合、配列の深さに関係なく一次元配列となるまで変換が実施されます。
arrayObj = [1, [2, [3, 4], 5], 6] p arrayObj.flatten
実行結果
$ruby sample.rb [1, 2, 3, 4, 5, 6]
引数指定あり
flattenメソッドに引数を指定する場合、指定した整数値分の階層だけ平坦化する処理が実施されます。
arrayObj = [1, [2, [3, 4], 5], 6] p arrayObj.flatten(0) p arrayObj.flatten(1) p arrayObj.flatten(2) p arrayObj.flatten(-1)
実行結果
$ruby sample.rb [1, [2, [3, 4], 5], 6] [1, 2, [3, 4], 5, 6] [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]
引数に指定した階層分だけ平坦化が実施されます。
各階層レベルでの処理結果の違いを確認しておきましょう。
一次元配列にflattenメソッドを実行する
では一次元配列に対してflattenメソッドを実行した場合、どのような処理結果となるのか確認しておきましょう。
arrayObj = [1, 2, 3, 4, 5, 6] p arrayObj.flatten
実行結果
$ruby sample.rb [1, 2, 3, 4, 5, 6]
一次元配列に対してflattenメソッドを実行した場合には、そのまま一次元配列のオブジェクトとして返却されます。
オブジェクト自体を変更するflatten!メソッド
flattenメソッドでは「flatten!」と記述することで、対象オブジェクト自体を変更してしまうことが可能です。
公式ドキュメントでは「flatten! は自身を再帰的かつ破壊的に平坦化し、平坦化が行われた場合は self をそうでない場合は nil を返します」と定義されています。
flattenメソッドとflatten!メソッドでそれぞれ実行後のオブジェクトを確認する
flattenメソッドで実行後のオブジェクトがどのようになっているか確認しておきましょう。
arrayObj = [1, [2, [3, 4], 5], 6] p arrayObj.flatten p arrayObj
実行結果
$ruby sample.rb [1, 2, 3, 4, 5, 6] [1, [2, [3, 4], 5], 6]
flattenオブジェクト利用時は平坦化が実施されていますが、元のオブジェクトが平坦化されたわけではないことをご確認頂けます。
サンプルを「flatten!」メソッドに書き換えてみましょう。
arrayObj = [1, [2, [3, 4], 5], 6] p arrayObj.flatten! p arrayObj
実行結果
$ruby sample.rb [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]
サンプルのように元のオブジェクト自体が平坦化されていることをご確認頂けます。
一次元配列にflatten!メソッド実行する
一次元配列に対してflatten!メソッドを実行した際の動きも確認しておきましょう。
arrayObj = [1, 2, 3, 4, 5, 6] p arrayObj.flatten! p arrayObj
実行結果
$ruby sample.rb nil [1, 2, 3, 4, 5, 6]
このように平坦化が実行出来ない場合には、元のオブジェクトがnilに変換されるわけではなく、あくまでflatten!メソッドの実行結果だけがnilとして処理されます。
ハッシュオブジェクトを一次元配列に変換するサンプル
ここからはハッシュオブジェクトを一次元配列に変換するサンプルを確認してみましょう。
公式ドキュメントでは「デフォルトではこのメソッドは自身を再帰的に平坦化しません」と記述されています。
引数指定なし
flattenメソッドに引数を指定しない場合、単純に配列化が実施されます。
hashObj = {"one" => 1, "two" =>[2, "二"], "three" => 3} p hashObj.flatten
実行結果
$ruby sample.rb ["one", 1, "two", [2, "二"], "three", 3]
引数指定あり
上記のサンプルで引数に値を設定した場合の出力情報を確認しておきましょう。
hashObj = {"one" => 1, "two" =>[2, "二"], "three" => 3} p hashObj.flatten(0) p hashObj.flatten(1) p hashObj.flatten(2) p hashObj.flatten(-1)
実行結果
$ruby sample.rb [["one", 1], ["two", [2, "二"]], ["three", 3]] ["one", 1, "two", [2, "二"], "three", 3] ["one", 1, "two", 2, "二", "three", 3] ["one", 1, "two", 2, "二", "three", 3]
このように指定する引数によってどこまで再帰的に平坦化するのかが決まるため、それぞれの処理結果の違いをしっかりと確認しておきましょう。
さいごに: Rubyのflattenメソッドで多次元を一次元に変換してみよう
本記事では、Rubyのflattenメソッドの使い方についてサンプルコードを掲載しながらご紹介してきました。
flattenメソッドは多次元オブジェクトを一次元配列に変換する機能として、主にAIなどの実装を行う際に利用されます。
再帰的に平坦化するというような日本語の説明を読むだけでは理解しづらい処理と言えますので、自分でもサンプルコードを積極的に動かしてみてどのような処理結果が返ってくるのかを確認してみてください。