也许只是我能力不足,在这里找到有关如何在Ruby中创建多维数组的内容,但我找不到任何信息。
请问有人可以给我一个如何创建多维数组的示例吗?
也许只是我能力不足,在这里找到有关如何在Ruby中创建多维数组的内容,但我找不到任何信息。
请问有人可以给我一个如何创建多维数组的示例吗?
严格来说,Ruby 不支持创建多维数组。但是可以将一个数组放入另一个数组中,这与多维数组几乎相同。
以下是在 Ruby 中创建二维数组的方法:
a = [[1,2,3], [4,5,6], [7,8,9]]
require 'narray'
b = NArray[ [1,2,3], [4,5,6], [7,8,9] ]
使用a[i][j]
来访问数组的元素。基本上,a[i]
返回存储在a
的第i
个位置的“子数组”,因此a[i][j]
返回存储在a
第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]]
(Array.new{Array.new})[2][2] = :value # => NoMethodError: undefined method '[]=' for nil:NilClass
- Patrick仅仅是澄清一下:
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]]
有两种初始化大小为 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"
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的元素。
最近我需要在Ruby中复制PHP风格的多维数组。以下是我的做法:
# 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
a = Array.new(2, Array.new(2, 0.0)); a[0][1] = 5; a # => [[0.0, 5], [0.0, 5]]
即使只设置了一次,5
也会出现在索引[0][1]
和[1][1]
处。 - Patrickclass 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
记住数组是 Ruby 中的一个对象,而对象不是(默认情况下)通过简单地命名它们或命名对象引用来创建的。以下是一个创建三维数组并将其转储到屏幕以进行验证的例程:
def Create3DimensionArray(x, y, z, default) n = 0 # 仅用于验证的代码 ar = Array.new(x) for i in 0...x ar[i] = Array.new(y) for j in 0...y ar[i][j] = Array.new(z, default) for k in 0...z # 仅用于验证的代码 ar[i][j][k] = n # 仅用于验证的代码 n += 1 # 仅用于验证的代码 end # 仅用于验证的代码 end end return ar end
# 创建样本并验证 ar = Create3DimensionArray(3, 7, 10, 0)
for x in ar puts "||" for y in x puts "|" for z in y printf "%d ", z end end end
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
matrix = [[1, 2], [3, 4]];
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
,但是在多维数组中就不太清楚了。
a[1][2][1]
而不是一些人可能期望的a[1,2,1]
。 - tadman