Mic*_*ant 1 ruby arrays initialization
我有
def initialize
@board = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
end
Run Code Online (Sandbox Code Playgroud)
我以为我可以缩短它:
def initialize
@board=[ [0] * 4] * 4
end
Run Code Online (Sandbox Code Playgroud)
它们看起来一样,但只有后者,我得到一个错误:
10) vertical turn can add 1 to an existing column of 2 with 1's at the ends [20/18949]
Failure/Error: expect([game.board[0][2], game.board[1][2], game.board[2][2], game.board[3][2]]).to eq [0,1,0,0]
expected: [0, 1, 0, 0]
got: [1, 1, 0, 1]
(compared using ==)
# ./spec/game_spec.rb:132:in `block (2 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)
试试你的工作和非工作代码:
@board.map { |x| x.object_id }
Run Code Online (Sandbox Code Playgroud)
你会看到差异.发生错误是因为所有内部数组都是同一个对象.
问题是
[ [0] * 4 ] * 4
Run Code Online (Sandbox Code Playgroud)
是一个包含相同数组四次的数组.
同时
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Run Code Online (Sandbox Code Playgroud)
是一个包含四个不同Array对象的Array.
当你.inspect他们看起来一样,因为Ruby没有向你展示对象id.
实现0-ed数组的另一种方法可能是:
Array.new(4) { Array.new(4) {0} }
Run Code Online (Sandbox Code Playgroud)
或者,如果您只处理4x4整数,那么您可以查看narray没有这些问题的库,并且对于批量操作也非常快.