web-dev-qa-db-ja.com

2次元配列を作成し、Rubyのサブ配列にアクセスします

2次元配列を作成し、その中の水平または垂直サブ配列にすばやくアクセスする可能性があるのだろうか?

次の場合に水平サブ配列にアクセスできると思います。

x = Array.new(10) { Array.new(20) }

x[6][3..8] = 'something'

しかし、私の知る限り、次のようにアクセスすることはできません。

x[3..8][6]

この制限を回避またはハッキングするにはどうすればよいですか?

66
gmile

2次元Arraysを実装する方法にはいくつかの問題があります。

a= [[1,2],[3,4]]
a[0][2]= 5 # works
a[2][0]= 6 # error

Hash as Array

多次元HashesArraysを使用することを好みます

a= Hash.new
a[[1,2]]= 23
a[[5,6]]= 42

これには、列または行を手動で作成する必要がないという利点があります。ハッシュへの挿入はほとんど O(1) であるため、Hashが大きくなりすぎない限り、ここに欠点はありません。

指定されていないすべての要素にデフォルト値を設定することもできます

a= Hash.new(0)

さて、サブアレイを取得する方法について

(3..5).to_a.product([2]).collect { |index| a[index] }
[2].product((3..5).to_a).collect { |index| a[index] }

(a..b).to_aはO(n)で実行されます。 Hashから要素を取得することはほぼO(1)であるため、収集はほぼO(n)で実行されます。 n個の要素のコピーは常にO(n)であるため、O(n)よりも高速にする方法はありません。

Hashesが大きくなりすぎると問題が発生する可能性があります。したがって、データ量が増えていることがわかっていれば、このように多次元Arrayを実装することをもう一度考えます。

93
johannes
rows, cols = x,y  # your values
grid = Array.new(rows) { Array.new(cols) }

要素へのアクセスに関しては、この記事は、希望する方法で配列をカプセル化するための段階的な方法に非常に適しています。

方法Ruby配列

31
shawnjan

あなたはあなたの実際の目標を述べていませんでしたが、おそらくこれは助けになるでしょう:

require 'matrix'  # bundled with Ruby
m = Matrix[
 [1, 2, 3],
 [4, 5, 6]
]

m.column(0) # ==> Vector[1, 4]

(およびベクターは配列のように機能します)

または、必要に応じて同様の表記法を使用します。

m.minor(0..1, 2..2) # => Matrix[[3], [6]]
30

これが3D配列の場合です

class Array3D
   def initialize(d1,d2,d3)
    @data = Array.new(d1) { Array.new(d2) { Array.new(d3) } }
   end

  def [](x, y, z)
    @data[x][y][z]
  end

  def []=(x, y, z, value)
    @data[x][y][z] = value
  end
end

他のRuby array。@data [0..2] [3..5] [8..10] = 0などのように、各配列のサブセクションにアクセスできます。

11
Mark Essel

x.transpose[6][3..8] または x[3..8].map {|r| r [6]}はあなたが欲しいものを与えるでしょう。

例:

a = [ [1,  2,  3,  4,  5],
      [6,  7,  8,  9,  10],
      [11, 12, 13, 14, 15],
      [21, 22, 23, 24, 25]
    ]

#a[1..2][2]  -> [8,13]
puts a.transpose[2][1..2].inspect   # [8,13]
puts a[1..2].map {|r| r[2]}.inspect  # [8,13]
5
pierrotlefou

これは非常に簡単なものになると確信しています

2.0.0p247 :032 > list = Array.new(5)

 => [nil, nil, nil, nil, nil] 

2.0.0p247 :033 > list.map!{ |x| x = [0] }

 => [[0], [0], [0], [0], [0]] 

2.0.0p247 :034 > list[0][0]

  => 0
2
vladCovaliov
a = Array.new(Array.new(4))

0.upto(a.length-1) do |i|
  0.upto(a.length-1) do |j|
    a[i[j]] = 1
  end
end

0.upto(a.length-1) do |i|
  0.upto(a.length-1) do |j|
    print a[i[j]] = 1 #It's not a[i][j], but a[i[j]]
  end
  puts "\n"
end
0
anon