代码之家  ›  专栏  ›  技术社区  ›  Redouane Red

克隆阵列及其内容

  •  27
  • Redouane Red  · 技术社区  · 9 年前

    我想复制一个数组,在不影响原始数组的情况下就地修改副本。此代码失败

    a = [
      '462664',
      '669722',
      '297288',
      '796928',
      '584497',
      '357431'
    ]
    b = a.clone
    b.object_id == a.object_id # => false
    a[1][2] = 'X'
    a[1] #66X722
    b[1] #66X722
    

    副本应与对象不同。为什么它看起来像是一个参考?

    6 回复  |  直到 9 年前
        1
  •  24
  •   jazzytomato    9 年前

    您需要对阵列进行深度复制。

    这是做这件事的方法

    Marshal.load(Marshal.dump(a))
    

    这是因为您克隆的是阵列,而不是其中的元素。因此,数组对象是不同的,但它包含的元素是相同的实例。例如,你也可以 a.each{|e| b << e.dup} 你的案子

        2
  •  23
  •   pjvleeuwen    5 年前

    而不是打电话 clone 在数组本身上,可以使用 map :

    b = a.map(&:clone)
    

    这在问题中所述的示例中有效,因为数组中的每个元素都有一个新实例。

        3
  •  9
  •   Zachary White    5 年前

    您可以使用#dup创建对象的浅副本,这意味着“复制对象的实例变量,但不复制它们引用的对象” 例如:

    a = [1, 2, 3]
    
    b = a.dup
    
    b # => [1, 2, 3]
    

    资料来源: https://ruby-doc.org/core-2.5.3/Object.html#method-i-dup

    编辑:听我下面的保罗说。我误解了这个问题。

        4
  •  7
  •   glee8e    8 年前

    试试看:

    b = [] #create a new array 
    b.replace(a) #replace the content of array b with the content from array a
    

    此时,这两个数组是对不同对象和内容的引用。

        5
  •  4
  •   cesartalves    4 年前

    您可以只映射数组的元素。我相信这是迄今为止最干净的解决方案。

    array.map(&:itself)

        6
  •  -1
  •   Anutosh    8 年前

    不确定,如果在其他地方回答了这个问题。尝试了搜索,但没有成功。

    试试这个

    current_array =["a", "b","c","d"]
    new_array = current_array[0 .. current_array.length]
    new_array[0] ="cool"
    
    output of new_array
     "cool","b","c","d"
    

    希望这有帮助。