代码之家  ›  专栏  ›  技术社区  ›  dangerousdave

复制字符串的Ruby数组

  •  10
  • dangerousdave  · 技术社区  · 14 年前
    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
    

    但它看起来并不优雅,也不高效。

    谢谢

    6 回复  |  直到 10 年前
        1
  •  11
  •   sepp2k    14 年前

    您的第二个解决方案可以缩短为 arr2 = arr.map do |e| e.dup end clone ,建议使用 dup 相反)。

    编辑:下面是一个递归的deep\u 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\u dup,否则仍然会得到这些容器的浅拷贝。

        2
  •  5
  •   James A. Rosen    14 年前

    arr = ["red","green","yellow"]
    arr2 = arr.inject([]) { |a,element| a << element.dup }
    
        3
  •  5
  •   Fabian    9 年前

    我也有类似的情况,非常关注速度。对我来说最快的方法就是利用 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
    
        4
  •  3
  •   9re    8 年前

    a 通过以下代码:

     Marshal.load(Marshal.dump(a))
    
        5
  •  2
  •   Ankit Vadi    8 年前

    看起来很简单。。只需运行以下代码:

    a = [1,2,3]
    b = [].replace(a)
    
    b[1] = 5
    
    puts a
    puts b
    

    运行以上代码,您将注意到其中的差异。干杯!

        6
  •  1
  •   fl00r    14 年前

    你可以使用这个技巧:

    arr1 = %w{ red green blue }
    arr2 = arr1.join("--!--").split("--!--")
    

    arr2[0].replace("lol")
    p arr1
    #=> ["red", "green", "blue"]
    p arr2
    #=> ["lol", "green", "blue"]
    

    它只适用于1级数组