Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyのtransposeメソッドで行を列に変換する方法

Rubyでグリッド状のデータ(多次元配列)を扱うときに便利なのが、Arrayクラスのtransposeメソッドです。この記事では、行と列を入れ替える「転置」の基本から、三目並べ(○×ゲーム)のような実践的な活用例までをわかりやすく解説します。

たとえば、3×3の正方形グリッドを多次元配列として持っているとしましょう。ここから「行を列に変換したい」という場面は意外とよくあります。

なぜそんなことが必要になるのでしょうか?

代表例が、古典的なゲームである三目並べです。

盤面をグリッドとして保存し、勝利判定を行うには、行・列・斜めのすべてをチェックしなければなりません。

ところが、グリッドを普通の配列として保持しているだけでは、直接アクセスできるのは「行」のみです。

面倒な方法:インデックス指定で列を取得する

ここでいう「直接アクセス」とは、eachmapなどで配列を走査する際に、必要以上のインデックス操作をしなくて済むという意味です。

具体例を見てみましょう。

まずはグリッドの定義です

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

イメージにすると次のようになります

Rubyのtransposeメソッドで行を列に変換する方法

インデックスを個別に参照すれば、列を取り出すことも不可能ではありません。

たとえば、最初の列を取得するコードはこちら

[grid[0][0], grid[1][0], grid[2][0]]

# [1, 4, 7]

一方、最初の行ならこれだけで済みます

grid[0]

# [1, 2, 3]

行と同じ手軽さで列を扱うには、どうすればよいのでしょうか?

簡単な方法:transposeメソッドを使う

答えはシンプルです。Array#transposeメソッドを呼ぶだけ。

使用例

columns = grid.transpose

はい、たったこれだけです!

これで最初の列も、次のように一行で取得できます:

columns[0]

# [1, 4, 7]

このように、標準ライブラリのメソッドをひとつ知っているだけで、コードの量と手間を大幅に減らせます 🙂

実践:三目並べ(Tic-Tac-Toe)への応用

ここではゲーム全体のコードは紹介しませんが、実際のプロジェクトでこのメソッドがどう役立つかのイメージをつかんでください。

三目並べで勝つためには、行・列・斜めのどれか一列を自分のマークで埋める必要があります。

行をチェックするコード

def check_rows
  @board.each { |row| return row.first if all_equal?(row) }
end

そして、列をチェックするコードがこちら

def check_columns
  @board.transpose.each { |row| return row.first if all_equal?(row) }
end

お気づきでしょうか? 両者の違いは、transposeを呼び出している点だけです!

補助的に使われているall_equal?メソッドは以下の通りです:

def all_equal?(row)
   return if row.first == nil

   row.each_cons(2).all? { |x,y| x == y }
 end

each_consメソッドの詳細については、Enumerableモジュールの解説記事をあわせて読んでみてください。

まとめ

この記事では、transposeメソッドについて学びました。

きちんとした形のグリッド(各行の要素数がそろった多次元配列)に対してtransposeを使えば、行を列へと変換でき、データへのアクセスが格段に楽になります。

なお、各行の要素数が異なる配列にtransposeを実行するとIndexErrorが発生するので、不揃いなデータを扱う場合は事前に整形しておきましょう。

本記事の内容が役に立ったと感じたら、書籍『Ruby Deep Dive』もぜひチェックしてみてください。

  1. RubyでNクイーン問題を解く方法【バックトラッキングの実装を徹底解説】

    N-Queens(Nクイーン)は、N×Nの盤面にN個のクイーンを配置する、非常に興味深いコーディングチャレンジです。 イメージは以下のようになります。 クイーンは全方向に移動できる駒です。 縦方向 横方向 斜め方向 この問題の解答(複数存在する場合もあります)では、すべてのクイーンを盤上に配置しつつ、どのクイーンも他のクイーンの攻撃範囲に入らないようにする必要があります。 この記事では、私がどのような思考プロセスで解答にたどり着いたのかを紹介します。 まずは計画を立てる この種のチャレンジに取り組むときは、まず平易な言葉で計画を書き出すことから始めるのが効果的です。 そうすることで、「何

  2. RubyのEnumerableモジュール入門ガイド〜筆者イチオシのeach_consメソッドを徹底解説〜

    Enumerableモジュールとは? Enumerableは繰り返し処理(イテレーション)用メソッドのコレクションで構成されるRubyのモジュールであり、Rubyが多くの開発者に愛される大きな理由のひとつとなっています。 Enumerableには、次のような便利なメソッドが含まれています: map select inject Enumerableのメソッドは、ブロックを渡すことで動作します。 ブロックの中には、各要素に対して実行したい処理を記述します。 例えば: [1,2,3].map { |n| n * 2 } このコードを実行すると、すべての数値が2倍になった新しい配列が得られます