迭代连接数组会改变原始数组中的项目.为什么?

jro*_*jro 2 ruby arrays loops concat concatenation

我遇到了Ruby数组的一些意外行为:

array1 = ["a"]
array2 = ["b"]
array3 =  array1 + array2

puts "array1 before array3.map!: #{array1}"
puts "array2 before array3.map!: #{array2}"
puts "array3 before array3.map!: #{array3}"

array3.map! { |item| item << "_modified" }

puts "array1  after array3.map!: #{array1}"
puts "array2  after array3.map!: #{array2}"
puts "array3  after array3.map!: #{array3}"
Run Code Online (Sandbox Code Playgroud)

终端输出:

array1 before array3.map!: ["a"]
array2 before array3.map!: ["b"]
array3 before array3.map!: ["a", "b"]
array1  after array3.map!: ["a_modified"]                #Unexpected
array2  after array3.map!: ["b_modified"]                #Unexpected
array3  after array3.map!: ["a_modified", "b_modified"]  #Expected
Run Code Online (Sandbox Code Playgroud)

第一个问题:尽管只迭代array3,为什么array1和array2中的项目不同?连接两个数组会返回一个新数组,那么为什么对array1和array2有延迟效果呢?

第二个问题:如何在不更改项目array1或array2的情况下通过迭代更改array3中的项目?

第三个问题:当使用.map和.each代替.map!时,输出是相同的.所以.each和.map似乎正在改变数组中的项目.为什么会这样?

Ama*_*dan 5

array1并且array2没有修改.字符串"a"并被"b"修改.

这样看:

string = "a"
array = [string, string, string] # ["a", "a", "a"]
string << "b"
array # ["ab", "ab", "ab"]
Run Code Online (Sandbox Code Playgroud)

阵列没有改变.它仍然是[string, string, string].但是string不同.

编辑为了澄清,并从注释重复,您没有修改数组.这是修改数组:

array3.each_index { |index| array3[index] = item + "_modified" }
Run Code Online (Sandbox Code Playgroud)

当你用另一个元素替换每个元素时.当你执行它array1array2打印不变时 - 它们的元素被踢出array3并被其他东西取代.你做了什么:

array3.map! { |item| item << "_modified" }
Run Code Online (Sandbox Code Playgroud)

附加"_modifier"到每个项目(不会弄乱其标识),然后map!array3 相同的元素替换每个元素.因此,array3仍然有相同的元件array1array2,并且在一个任何变化反映在其他.