hellkite 日記と雑記とメモ。

Shiki Kazamaの駄文と音楽と、時々技術な感じ

再び、Rubyで多次元配列


スポンサーリンク


この前はオセロの盤の状態格納で2次元配列が必要だった。で、テトリス作ろう*1としたらやっぱり2次元配列が必要。というわけで、もう一度、Rubyで多次元配列を実現するためにはどうすればいいのか調べてみた。


まずは、前回やった、配列を宣言してさらにその中に配列を宣言する方法。

array = Array.new(5,nil)
array.length.times do |i|
    array[i] = Array.new(5,0)
end

array[3][4] = 20
array[3][4]
#=> 20

Rubyに多次元配列がない件について - hellkite 日記と雑記とメモ。のコメントで教えてもらった書き方、

array = Array.new(5){ |i| Array.new(5,0) }

array[3][4] = 20
array[3][4]
#=> 20

これ、教えてもらったときは、内心わかりにくい・・・*2と思ったんですが、Rubyの表記になれてきたのか、この書き方わかりやすい!って思うようになってきたw


ここまでは、復習。これからが本題。
メーリングリストの中からこんなやり方があるってのを発見。

  1. []メソッドを再定義して多次元配列クラスを作ってしまう
  2. Rengeのmapを二重に使うことで多次元配列を作る
  3. narrayライブラリを使う
  4. キーにArrayを格納したHashで擬似的に表現する

1つ目はちょっと大掛かりなので、今回はパス。[]メソッドも再定義することができることは覚えておこう。


2つ目のコードはこんな感じになる。

array = (0..4).map { (0..4).map { 0 } }

array[3][4] = 20
array[3][4]
#=> 20

うーん・・・。(0..4)って表記が慣れない。けど、1番しっくりきそう。と思ったら、こう書けるじゃん。

array = 5.times.map { 5.times.map {0} }


3つ目のnarrayライブラリは数値計算で多次元配列を使う定番だそうです。なので、今回はパス。


問題の4つ目。これはHashを使って擬似的に配列を表現する。
コードはこんな感じ。

hash = {}
5.times { |i| 5.times { |j| hash[[i,j]] = 0 } }

hash[[3,4]] = 20
hash[[3,4]]
#=> 20

1行目の宣言が必要なのがちょっとうざい。要素にアクセスするための二重のカッコもうざい。
でも、Arrayとは違うアルゴリズムだから検索速度とかに差が出るような気がする。なんとなく、Hashって要素数が膨大になってもアクセス時間が均等っていうイメージがあるんだけど。
規模が大きくて速度を優先しないといけないってなったら、これがいいかもしれない*3


うん。なんか慣れてくると書き方のレパートリーも増えてきますね。
このエントリ書いていて気が付いたんだけど、以前コメント頂いたid:murase_syukaさんってruby-processing使いなのね。むしろ、ruby-processing始めるときにブログ参考にさせてもらってました。気づかなかった。感謝、感謝です。