复制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

    Interesting Posts