在Ruby中创build二维数组并访问子数组

我想知道是否有可能创build一个二维数组,并快速访问其中的任何水平或垂直的子数组?

我相信我们可以在以下情况下访问一个水平的子数组:

x = Array.new(10) { Array.new(20) } x[6][3..8] = 'something' 

但据我所知,我们不能这样访问它:

 x[3..8][6] 

我怎样才能避免或破解这个限制?

二维Arrays的实现方式存在一些问题。

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

HashArray

我更喜欢使用Hashes Arrays

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

这样做的好处是,您不必手动创build列或行。 插入散列几乎是O(1) ,所以这里没有什么缺点,只要你的Hash不会太大。

您甚至可以为所有未指定的元素设置默认值

 a= Hash.new(0) 

那么现在谈谈如何获得子arrays

 (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)。 现在有办法使它比O(n)更快,因为拷贝n个元素总是O(n)。

Hashes值过大时可能会出现问题。 所以,如果我知道我的数据量越来越大,我会考虑实施一个像这样的多维Array

你没有说明你的实际目标,但也许这可以帮助:

 require 'matrix' # bundled with Ruby m = Matrix[ [1, 2, 3], [4, 5, 6] ] m.column(0) # ==> Vector[1, 4] 

(和vector行为像数组)

或者使用类似的符号,如你所愿:

 m.minor(0..1, 2..2) # => Matrix[[3], [6]] 
 rows, cols = x,y # your values grid = Array.new(rows) { Array.new(cols) } 

至于访问元素,这篇文章是非常好的一步一步的方式来封装一个数组,以你想要的方式:

如何rubyarrays

这是一个三维数组的情况

 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数组一样访问每个数组的子部分。 @数据[0..2] [3..5] [8..10] = 0等

x.transpose[6][3..8]或者x[3..8].map {|r| r [6]} 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] 

我很确定这可以是非常简单的

 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 
 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 

这是简单的版本

  #one a = [[0]*10]*10 #two row, col = 10, 10 a = [[0]*row]*col 

这是创build“2D”数组的简单方法。

 2.1.1 :004 > m=Array.new(3,Array.new(3,true)) => [[true, true, true], [true, true, true], [true, true, true]]