Существует ли простой способ копировать многомерный массив в Ruby?

У меня есть 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, испытывающего недостаток во встроенной поддержке многомерных массивов, или является там простой встроенной функцией, чтобы сделать это, что я отсутствовал?

17
задан brad 11 January 2010 в 00:20
поделиться

4 ответа

Вот способ обработки " Ruby-esque ":

temp_array = Marshal.load (Marshal.dump (your_array_to_be_cloned))

33
ответ дан 30 November 2019 в 13:27
поделиться

Как указали другие люди, вы можете использовать клон. Это не будет работать, однако, как это неглубокая копия, поэтому подменные массивы (это не очень многомерное массив, я думаю) не будет клонирован. Поскольку массивы являются смежными объектами в 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 (маршал. Дамп (массив)) - также будет работать для хэшей и так далее, так что это лучше.

4
ответ дан 30 November 2019 в 13:27
поделиться

Вы можете использовать Array.Clone , как указано здесь . Это даст вам копию оригинального объекта, а не только указателя.

-9
ответ дан 30 November 2019 в 13:27
поделиться

Попробуйте это:

temp_array = array.clone
-8
ответ дан 30 November 2019 в 13:27
поделиться
Другие вопросы по тегам:

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