Rubymultidimensional array
也许这只是我缺乏在这里find问题的能力,但是我找不到在Ruby中如何创buildmultidimensional array的任何事情。
有人请给我一个例子,如何做到这一点?
严格地说,在Ruby中不可能创buildmultidimensional array。 但是可以将数组放在另一个数组中,这与multidimensional array几乎相同。
这是你如何在Ruby中创build二维数组:
a = [[1,2,3], [4,5,6], [7,8,9]]
如注释中所述,您也可以使用一个Ruby数值数组库: NArray :
require 'narray' b = NArray[ [1,2,3], [4,5,6], [7,8,9] ]
使用a[i][j]
来访问数组的元素。 基本上a[i]
返回存储在位置i
上的“子数组”,因此a[i][j]
从存储在位置i
上的数组中返回元素编号j
。
您可以将一个块传递给Array.new
Array.new(n) {Array.new(n,default_value)}
返回块的值将是第一个数组的每个索引的值,
所以..
Array.new(2) {Array.new(2,5)} #=> [[5,5],[5,5]]
你可以使用array[x][y]
来访问这个数组
对于第二个数组实例,也可以传递一个块作为默认值。 所以
Array.new(2) { Array.new(3) { |index| index ** 2} } #=> [[0, 1, 4], [0, 1, 4]]
只是澄清:
arr = Array.new(2) {Array.new(2,5)} #=> [[5,5],[5,5]]
并不完全相同:
arr = Array.new(2, Array.new(2, 5))
在后面的情况下,请尝试:
arr[0][0] = 99
这就是你得到的:
[[99,5], [99,5]]
上面给出的方法不起作用。
n = 10 arr = Array.new(n, Array.new(n, Array.new(n,0.0))) arr[0][1][2] += 1 puts arr[0][2][2]
相当于
n = 10 a = Array.new(n,0.0) b = Array.new(n,a) arr = Array.new(n, b) arr[0][1][2] += 1 puts arr[0][2][2]
并打印1.0,而不是0.0,因为我们正在修改数组a和打印数组a的元素。
有两种方法来初始化多个数组(大小为2)。 所有其他的答案都显示了一个默认值的例子。
声明每个子数组(可以在运行时执行):
multi = [] multi[0] = [] multi[1] = []
或在初始化时声明父数组的大小:
multi = Array.new(2) { Array.new }
用法示例:
multi[0][0] = 'a' multi[0][1] = 'b' multi[1][0] = 'c' multi[1][1] = 'd' p multi # [["a", "b"], ["c", "d"]] p multi[1][0] # "c"
所以你可以用第一种方式来包装,像这样使用它:
@multi = [] def multi(x, y, value) @multi[x] ||= [] @multi[x][y] = value end multi(0, 0, 'a') multi(0, 1, 'b') multi(1, 0, 'c') multi(1, 1, 'd') p @multi # [["a", "b"], ["c", "d"]] p @multi[1][0] # "c"
最近我不得不在Ruby中重现PHP风格的multidimensional array。 这是我做的:
# Produce PHP-style multidimensional array. # # Example # # arr = Marray.new # # arr[1][2][3] = "foo" # => "foo" # # arr[1][2][3] # => "foo" class Marray < Array def [](i) super.nil? ? self[i] = Marray.new : super end end
其实这比上面给出的块方法快得多:
arr = Array.new(n, Array.new(n, Array.new(n,0.0))) arr[0][1][2] += 1
也许你可以用哈希模拟你的multidimensional array。 哈希键可以由任何Ruby对象,所以你也可以采取一个数组。
例:
marray = {} p marray[[1,2]] #-> nil marray[[1,2]] = :a p marray[[1,2]] #-> :a
基于这个想法,你可以定义一个新的类。
只是一个快速的情况:
=begin rdoc Define a multidimensional array. The keys must be Fixnum. The following features from Array are not supported: * negative keys (Like Array[-1]) * No methods <<, each, ... =end class MArray INFINITY = Float::INFINITY =begin rdoc =end def initialize(dimensions=2, *limits) @dimensions = dimensions raise ArgumentError if limits.size > dimensions @limits = [] 0.upto(@dimensions-1){|i| @limits << (limits[i] || INFINITY) } @content = {} end attr_reader :dimensions attr_reader :limits =begin rdoc =end def checkkeys(keys) raise ArgumentError, "Additional key values for %i-dimensional Array" % @dimensions if keys.size > @dimensions raise ArgumentError, "Missing key values for %i-dimensional Array" % @dimensions if keys.size != @dimensions raise ArgumentError, "No keys given" if keys.size == 0 keys.each_with_index{|key,i| raise ArgumentError, "Exceeded limit for %i dimension" % (i+1) if key > @limits[i] raise ArgumentError, "Only positive numbers allowed" if key < 1 } end def[]=(*keys) data = keys.pop checkkeys(keys) @content[keys] = data end def[](*keys) checkkeys(keys) @content[keys] end end
这可以用作:
arr = MArray.new() arr[1,1] = 3 arr[2,2] = 3
如果你需要一个预定义的matrix2x2,你可以使用它:
arr = MArray.new(2,2,2) arr[1,1] = 3 arr[2,2] = 3 #~ arr[3,2] = 3 #Exceeded limit for 1 dimension (ArgumentError)
我可以想象如何处理命令,如<<
或二维数组中的each
一个,而不是多维的。
这可能有助于记住数组是Ruby中的一个对象,并且对象不是(默认情况下)仅仅通过命名或命名对象引用来创build。 这是创build一个3维数组并将其转储到屏幕进行validation的例程:
def Create3DimensionArray(x,y,z,默认) 只有0#validation码 ar = Array.new(x) 我在0 ... x ar [i] = Array.new(y) 对于0 ... y中的j ar [i] [j] = Array.new(z,默认) 对于仅在0 ... z#validation码中的k ar [i] [j] [k] = n#validation码 仅限n + = 1#validation码 只有结束#validation码 结束 结束 返回ar 结束 #创build示例并validation ar = Create3DimensionArray(3,7,10,0) 对于ar 把“||” 对于x中的y 把“|” 为z在y printf“%d”,z 结束 结束 结束
下面是ruby中3D数组类的实现,在这种情况下,默认值是0
class Array3 def initialize @store = [[[]]] end def [](a,b,c) if @store[a]==nil || @store[a][b]==nil || @store[a][b][c]==nil return 0 else return @store[a][b][c] end end def []=(a,b,c,x) @store[a] = [[]] if @store[a]==nil @store[a][b] = [] if @store[a][b]==nil @store[a][b][c] = x end end array = Array3.new array[1,2,3] = 4 puts array[1,2,3] # => 4 puts array[1,1,1] # => 0