Дублирование массива строк Ruby

arr = ["red","green","yellow"]

arr2 = arr.clone
arr2[0].replace("blue")

puts arr.inspect
puts arr2.inspect

производит:

["blue", "green", "yellow"]
["blue", "green", "yellow"]

Должен там так или иначе сделать глубокую копию массива строк, кроме использования Маршала, поскольку я понимаю, что это - взлом.

Я мог сделать:

arr2 = []
arr.each do |e|
  arr2 << e.clone
end

но это не кажется очень изящным, или эффективным.

Спасибо

10
задан dangerousdave 16 August 2014 в 13:54
поделиться

3 ответа

Ваше второе решение можно сократить до arr2 = arr.map do |e| e.dup end (если вам не нужно поведение clone, рекомендуется использовать dup).

В остальном ваши два решения являются стандартными решениями для выполнения глубокого копирования (хотя вторая версия является только одноуровневой (т.е. если вы используете ее для массива массивов строк, вы все еще можете мутировать строки)). На самом деле более удобного способа нет.

Edit: Вот рекурсивный метод 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), иначе вы все равно получите неглубокую копию для них.

10
ответ дан 3 December 2019 в 16:09
поделиться

Я рекомендую вашу первоначальную идею, но написанную немного более сжато:

arr = ["red","green","yellow"]
arr2 = arr.inject([]) { |a,element| a << element.dup }
5
ответ дан 3 December 2019 в 16:09
поделиться

Вы можете использовать этот прием:

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

Но это просто для развлечения :)

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

И он будет работать только для массивов 1 уровня

1
ответ дан 3 December 2019 в 16:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: