У меня есть 2-мерный массив в Ruby, из которого я хочу произвести рабочий дубликат. Очевидно, я не могу сделать этого;
array=[[3,4],[5,9],[10,2],[11,3]]
temp_array=array
как любые модификации, которые я делаю к temp_array, будут также сделаны выстроить, поскольку я просто скопировал идентификатор объекта. Я думал, что буду в состоянии обойти это путем простого использования;
temp_array=array.dup
но это не работает, поскольку temp_array является просто массивом идентификаторов объектов, которые дублированы так, я все еще заканчиваю тем, что изменил начальный массив (если я понимаю то, что пошло не так, как надо, когда я сделал это). Решение, которое я нашел, состояло в том, чтобы сделать следующее;
temp_array=[]
array.each{|sub| temp_array << sub.dup}
Это достигает того, что я хочу, но, кажется, неловкий способ решить мою проблему.
Я обеспокоен тем, как это работало бы, если бы я не знал то, чем мой массив был содержащий (например, если было возможно, что некоторые части массива имели 3 размера). Я должен был бы потенциально протестировать класс каждого члена массива, чтобы видеть, должен ли он был быть выполнен с помощью итераций для дублирования его. Не невозможная задача вообще, но это кажется грязным мне. Это - просто последствие Ruby, испытывающего недостаток во встроенной поддержке многомерных массивов, или является там простой встроенной функцией, чтобы сделать это, что я отсутствовал?
Вот способ обработки " Ruby-esque ":
temp_array = Marshal.load (Marshal.dump (your_array_to_be_cloned))
Как указали другие люди, вы можете использовать клон. Это не будет работать, однако, как это неглубокая копия, поэтому подменные массивы (это не очень многомерное массив, я думаю) не будет клонирован. Поскольку массивы являются смежными объектами в Ruby, подменные массивы будут изменены. Например, проверьте это
>> blah = [[3,5],6]
=> [[3, 5], 6]
>> joe = blah.clone
=> [[3, 5], 6]
>> joe[0]
=> [3, 5]
>> joe[0].push "blah"
=> [3, 5, "blah"]
>> blah
=> [[3, 5, "blah"], 6]
, так как вы можете видеть, просто делать клон не будет работать. Но вы знали, что, отсюда, ваш вопрос.
Я приготовил это только сейчас. Это будет делать, пока вы не узнаете реальный, рубин путь, чтобы сделать это (я просто работаю в Руби, я не эксперт).
def dup_recursive(new_array, old_array)
old_array.each do |item|
if item.class == Array
new_array << dup_recursive([], item)
else
new_item = item.dup rescue new_item = item # in case it's got no dupe, like FixedNum
new_array << new_item
end
new_array
end
end
array=[[3,[9,12]],[5,9],[10,2],[11,3]]
new_array = Array.new
dup_recursive(new_array, array)
puts array.inspect
puts new_array.inspect
Я знаю, я не использую стипендию утки, но я буду рад, что должен учиться о том, как это сделать, не просищая класс рассматриваемого объекта.
Редактировать: Я должен был только что искать на глубоком клонировании Ruby в Google, но иногда мне нравится писать код :) ... В любом случае, другой решение, представленный - Marshal.load (маршал. Дамп (массив))
- также будет работать для хэшей и так далее, так что это лучше.
Вы можете использовать Array.Clone
, как указано здесь . Это даст вам копию оригинального объекта, а не только указателя.