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

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

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

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


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

但据我所知,我们不能这样进去:

x[3..8][6]

如何避免或突破这个限制?

153512 次浏览
rows, cols = x,y  # your values
grid = Array.new(rows) { Array.new(cols) }

至于访问元素,本文非常适合按照您希望的方式逐步封装数组:

如何使用 Ruby 数组

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]

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

这样做的好处是,您不必手动创建列或行。插入散列几乎是 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)中。没有办法使它比 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]

(矢量的作用类似于数组)

或者,按照您的需要使用类似的记号:

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

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

这是简单的版本

 #one
a = [[0]*10]*10


#two
row, col = 10, 10
a = [[0]*row]*col
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

我相信这很简单

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

这里有一个创建“2D”数组的简单方法。

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


=> [[true, true, true], [true, true, true], [true, true, true]]