迭代串联数组会改变原始数组中的项目。为什么?
Iterating over a concatenated array alters the items in the original arrays. Why?
我遇到了 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}"
终端输出:
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
第一个问题:为什么 array1 和 array2 中的项目尽管只迭代了 array3?连接两个数组 returns 一个新数组,那么为什么array1和array2会有挥之不去的影响?
第二个问题:如何在不更改array1或array2的项目的情况下通过迭代更改array3中的项目?
第三个问题:当使用.map 和.each 代替.map! 时,输出是相同的。所以看起来 .each 和 .map 正在改变数组中的项目。为什么会出现这种情况?
array1
和 array2
没有被修改。字符串 "a"
和 "b"
被修改。
这样看:
string = "a"
array = [string, string, string] # ["a", "a", "a"]
string << "b"
array # ["ab", "ab", "ab"]
数组没有变化。还是[string, string, string]
。但是string
就不一样了。
EDIT 为了澄清并重复评论,您没有修改数组。这是修改数组:
array3.each_index { |index| array3[index] = item + "_modified" }
当你用另一个元素替换每个元素时。当你执行这个时,array1
和 array2
打印不变 - 它们的元素被踢出 array3
并被其他东西取代。你做了什么:
array3.map! { |item| item << "_modified" }
将 "_modifier"
附加到每个项目(不混淆其标识),然后 map!
将 array3
中的每个元素替换为相同的元素.因此,array3
仍然具有与 array1
和 array2
相同的元素,其中一个的任何更改都会反映在另一个中。
我遇到了 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}"
终端输出:
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
第一个问题:为什么 array1 和 array2 中的项目尽管只迭代了 array3?连接两个数组 returns 一个新数组,那么为什么array1和array2会有挥之不去的影响?
第二个问题:如何在不更改array1或array2的项目的情况下通过迭代更改array3中的项目?
第三个问题:当使用.map 和.each 代替.map! 时,输出是相同的。所以看起来 .each 和 .map 正在改变数组中的项目。为什么会出现这种情况?
array1
和 array2
没有被修改。字符串 "a"
和 "b"
被修改。
这样看:
string = "a"
array = [string, string, string] # ["a", "a", "a"]
string << "b"
array # ["ab", "ab", "ab"]
数组没有变化。还是[string, string, string]
。但是string
就不一样了。
EDIT 为了澄清并重复评论,您没有修改数组。这是修改数组:
array3.each_index { |index| array3[index] = item + "_modified" }
当你用另一个元素替换每个元素时。当你执行这个时,array1
和 array2
打印不变 - 它们的元素被踢出 array3
并被其他东西取代。你做了什么:
array3.map! { |item| item << "_modified" }
将 "_modifier"
附加到每个项目(不混淆其标识),然后 map!
将 array3
中的每个元素替换为相同的元素.因此,array3
仍然具有与 array1
和 array2
相同的元素,其中一个的任何更改都会反映在另一个中。