复制Ruby字符串数组
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
但它似乎并不优雅或高效。
谢谢
您的第二个解决方案可以缩短为arr2 = arr.map do |e| e.dup end
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
您可能还想为其他容器(如Hash)定义deep_dup,否则您仍然可以获得浅层副本。
我建议你最初的想法,但写得更简洁:
arr = ["red","green","yellow"] arr2 = arr.inject([]) { |a,element| a << element.dup }
我处于类似的情况,非常关心速度。 对我来说最快的方法是使用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
您可以通过以下代码制作数组a
的深层副本:
Marshal.load(Marshal.dump(a))
它看起来很简单..只需运行以下代码:
a = [1,2,3] b = [].replace(a) b[1] = 5 puts a puts b
运行上面的代码,你会发现差异。 干杯!
你可以使用这个hack:
arr1 = %w{ red green blue } arr2 = arr1.join("--!--").split("--!--")
但它只是为了好玩:)
arr2[0].replace("lol") p arr1 #=> ["red", "green", "blue"] p arr2 #=> ["lol", "green", "blue"]
它只适用于1级arrays