Я признаю, что я немного новичок в рубине (сейчас пишу сценарии рейка). На большинстве языков легко найти конструкторы копирования. Полчаса поиска не нашел его в рубине. Я хочу создать копию хэша, чтобы я мог изменить ее, не затрагивая исходный экземпляр.
Некоторые ожидаемые методы, которые не работают должным образом:
h0 = { "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1=Hash.new(h0)
h2=h1.to_hash
В то же время я прибег к этому неумелому обходному пути
def copyhash(inputhash)
h = Hash.new
inputhash.each do |pair|
h.store(pair[0], pair[1])
end
return h
end
Hash
объектами, предоставленный ответ будет хорошим. Если вы имеете дело с хеш-подобными объектами, которые происходят из мест, которые вы не контролируете, вам следует подумать, хотите ли вы, чтобы синглтон-класс, связанный с хеш-копированием, дублировался или нет. См. Stackoverflow.com/questions/10183370/…Ответы:
Этот
clone
метод является стандартным, встроенным в Ruby способом создания мелкой копии :Обратите внимание, что поведение может быть переопределено:
источник
Marshal.load(Marshal.dump(h))
.Как уже отмечали другие,
clone
сделаем это. Имейте в виду, чтоclone
из хэша создается мелкая копия. То есть:Происходит то, что ссылки хеша копируются, а не объекты, на которые ссылаются ссылки.
Если вам нужна глубокая копия, тогда:
deep_copy
работает для любого объекта, который можно маршалировать. Большинство встроенных типов данных (Array, Hash, String и т. Д.) Можно упорядочить.Marshalling - это имя Руби для сериализации . При маршаллинге объект - вместе с объектами, на которые он ссылается - преобразуется в серию байтов; эти байты затем используются для создания другого объекта, такого как оригинал.
источник
Marshal.load(Marshal.dump(o))
глубокое копирование? Я не могу понять, что происходит за кулисамиh1[:a] << 'bar'
вы изменяете исходный объект (строка указывает h1 [: а]) , но если вы должны были сделатьh1[:a] = "#{h1[:a]}bar"
вместо этого, вы можете создать новый строковый объект, и точкаh1[:a]
в том , что, в то время какh2[:a]
IS по-прежнему указывает на старую (неизмененную) строку.Если вы используете Rails, вы можете сделать:
http://apidock.com/rails/Hash/deep_dup
источник
Хеш может создать новый хеш из существующего хеша:
источник
Я также новичок в Ruby и столкнулся с похожими проблемами при дублировании хэша. Используйте следующее. Я понятия не имею о скорости этого метода.
источник
Как упоминалось в разделе «Вопросы безопасности» документации маршала ,
Вот пример того, как сделать клонирование с использованием JSON в Ruby:
источник
Используйте
Object#clone
:(Путаница в документации
clone
говорит, чтоinitialize_copy
это способ переопределить это, но ссылка для этого методаHash
указываетreplace
вместо этого ...)источник
Поскольку стандартный метод клонирования сохраняет замороженное состояние, он не подходит для создания новых неизменяемых объектов на основе исходного объекта, если вы хотите, чтобы новые объекты немного отличались от исходного (если вам нравится программирование без сохранения состояния).
источник
Клон медленный. Для производительности, вероятно, следует начинать с пустого хэша и слияния. Не распространяется на случай вложенных хэшей ...
источник
Это особый случай, но если вы начинаете с предопределенного хэша, который вы хотите получить и скопировать, вы можете создать метод, который возвращает хеш:
У меня был особый сценарий: у меня была коллекция хэшей JSON-схемы, где одни хэши строили из других. Я изначально определял их как переменные класса и столкнулся с этой проблемой копирования.
источник
Вы можете использовать ниже для глубокого копирования объектов Hash.
источник
Поскольку у Ruby есть миллион способов сделать это, вот еще один способ использования Enumerable:
источник
Альтернативный способ Deep_Copy, который работал для меня.
Это привело к созданию deep_copy, поскольку h2 формируется с использованием представления массива h1, а не ссылок h1.
источник