arr = ["red","green","yellow"]
arr2 = arr.clone
arr2[0].replace("blue")
puts arr.inspect
puts arr2.inspect
产生
["blue", "green", "yellow"]
["blue", "green", "yellow"]
有没有做一个字符串数组的深层副本,除了使用Marshal,因为我知道这是一个黑客。
我能做到:
arr2 = []
arr.each do |e|
arr2 << e.clone
end
但它似乎并不优雅或高效。
由于
答案 0 :(得分:10)
您的第二个解决方案可以缩短为arr2 = arr.map do |e| e.dup end
(除非您确实需要clone
的行为,否则建议您改为使用dup
。
除此之外,你的两个解决方案基本上是执行深层复制的标准解决方案(虽然第二个版本只有一个级别的深度(即如果你在一个字符串数组的数组上使用它,你仍然可以改变字符串))。没有更好的方式。
编辑:这是一个递归的deep_dup方法,适用于任意嵌套的数组:
class Array
def deep_dup
map {|x| x.deep_dup}
end
end
class Object
def deep_dup
dup
end
end
class Numeric
# We need this because number.dup throws an exception
# We also need the same definition for Symbol, TrueClass and FalseClass
def deep_dup
self
end
end
你可能还想为其他容器定义deep_dup(比如Hash),否则你仍然可以得到那些容器的浅层副本。
答案 1 :(得分:5)
我建议你最初的想法,但写得更简洁:
arr = ["red","green","yellow"]
arr2 = arr.inject([]) { |a,element| a << element.dup }
答案 2 :(得分:5)
我处于类似情况,非常关心速度。对我来说最快的方法是使用map{&:clone}
所以试试这个:
pry(main)> a = (10000..1000000).to_a.shuffle.map(&:to_s)
pry(main)> Benchmark.ms { b = a.deep_dup }
=> 660.7760030310601
pry(main)> Benchmark.ms { b = a.join("--!--").split("--!--") }
=> 605.0828141160309
pry(main)> Benchmark.ms { b = a.map(&:clone) }
=> 450.8283680770546
答案 3 :(得分:3)
您可以通过以下代码制作数组a
的深层副本:
Marshal.load(Marshal.dump(a))
答案 4 :(得分:2)
看起来很简单..只需运行以下代码:
a = [1,2,3]
b = [].replace(a)
b[1] = 5
puts a
puts b
运行上面的代码,你会发现差异。干杯!
答案 5 :(得分:1)
你可以使用这个黑客:
arr1 = %w{ red green blue }
arr2 = arr1.join("--!--").split("--!--")
但这只是为了好玩:)
arr2[0].replace("lol")
p arr1
#=> ["red", "green", "blue"]
p arr2
#=> ["lol", "green", "blue"]
它只适用于1级数组