在块外部定义空数组,在块内,将其分配给新变量。如果新数组发生更改,则空数组也会修改其值。为什么呢?
# THIS CODE CHECK WHICH LETTERS IN klas APPEAR IN docs
klas = ["a", "b", "c"]
docs = [[1, "a"], [2, "a"], [3, "b"], [4, "b"], [5, "c"], [6, "c"]]
output = []
empty_array = Array.new(klas.size) { 0 } # EMPTY ARRAY DEFINED HERE
docs.each do |doc|
puts empty_array.inspect
puts (output_row = empty_array).inspect # EMPTY ARRAY ASSIGNED TO ANOTHER
# FIND INDEX OF THE LETTER IN klas FROM docs. ASSIGN 1.
output_row[klas.index(doc[1])] = 1 # PROBLEM! THIS ALSO CHANGES THE EMPTY ARRAY VALUES
output << output_row
end
CONSOLE OUTPUT显示空数组根据另一个数组
更改其值###
empty_array is [0, 0, 0]
output_row is [0, 0, 0]
---
###
empty_array is [1, 0, 0]
output_row is [1, 0, 0]
---
###
empty_array is [1, 0, 0]
output_row is [1, 0, 0]
---
###
empty_array is [1, 1, 0]
output_row is [1, 1, 0]
---
###
empty_array is [1, 1, 0]
output_row is [1, 1, 0]
---
###
empty_array is [1, 1, 1]
output_row is [1, 1, 1]
---
# INCORRECT output IS
=> [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]
# SHOULD BE
=> [[1, 0, 0], [1, 0, 0], [0, 1, 0], [0, 1, 0], [0, 0, 1], [0, 0, 1]]
但是如果在块中定义了空数组并将其分配给新变量,则它按预期工作。
docs.each do |doc|
empty_array = Array.new(klas.size) { 0 } # THIS MAKES SURE empty_array stays with zero values
output_row = empty_array
output_row[klas.index(doc[1])] = 1
output << output_row
end
CORRECT output IS
=> [[1, 0, 0], [1, 0, 0], [0, 1, 0], [0, 1, 0], [0, 0, 1], [0, 0, 1]]
为什么空数组在块外时修改其值?不管另一个阵列改变它的值,它不应该保持不变吗?
答案 0 :(得分:4)
使用
output_row = empty_array
你没有复制空数组。您正在创建对empty_array
中引用的相同基础数组的引用。
您可以创建克隆或数组的副本。所以使用:
output_row = empty_array.dup
这将创建一个新的数组,它与empty_array重复,请参阅http://ruby-doc.org/core-2.4.1/Object.html#method-i-dup
有关示例的更详细说明:
a = [1] => [1] # is creating a new array 'x'
# a is referencing this array, a is not the array itself!
b = a => [1] # b now references the array 'x'
a = [2] => [2] # is creating a new array 'y', a is referencing this new array
# the reference of b is not changing
b => [1] # b still pointing to array 'x'
因此,对于b = a
,您只需告诉他们引用相同的数组x
,但b
不是对a
的引用。