在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
Hash
为Array
我更喜欢使用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]]