[ruby] Ruby에서 해시를 어떻게 복사합니까?

나는 내가 약간의 루비 초보자임을 인정할 것입니다 (지금 레이크 스크립트 작성). 대부분의 언어에서 복사 생성자를 쉽게 찾을 수 있습니다. 30 분 동안 검색하면 루비에서 찾지 못했습니다. 원본 인스턴스에 영향을 미치지 않고 해시 복사본을 만들려고합니다.

의도 한대로 작동하지 않는 일부 예상되는 방법 :

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



답변

clone방법은 얕은 복사 를 수행하는 Ruby의 표준 내장 방법입니다 .

irb(main):003:0> h0 = {"John" => "Adams", "Thomas" => "Jefferson"}
=> {"John"=>"Adams", "Thomas"=>"Jefferson"}
irb(main):004:0> h1 = h0.clone
=> {"John"=>"Adams", "Thomas"=>"Jefferson"}
irb(main):005:0> h1["John"] = "Smith"
=> "Smith"
irb(main):006:0> h1
=> {"John"=>"Smith", "Thomas"=>"Jefferson"}
irb(main):007:0> h0
=> {"John"=>"Adams", "Thomas"=>"Jefferson"}

동작이 재정의 될 수 있습니다.

이 메서드에는 클래스 별 동작이있을 수 있습니다. 그렇다면, 그 행동은 #initialize_copy클래스 의 방법 으로 문서화 될 것 입니다.


답변

다른 사람들이 지적했듯이 clone그렇게 할 것입니다. 주의하십시오 clone해시의 얕은 복사본을 만듭니다. 즉 말하자면:

h1 = {:a => 'foo'}
h2 = h1.clone
h1[:a] << 'bar'
p h2                # => {:a=>"foobar"}

일어나는 일은 해시의 참조가 복사되고 있지만 참조가 참조하는 객체는 아닙니다.

깊은 사본을 원한다면 다음을 수행하십시오.

def deep_copy(o)
  Marshal.load(Marshal.dump(o))
end

h1 = {:a => 'foo'}
h2 = deep_copy(h1)
h1[:a] << 'bar'
p h2                # => {:a=>"foo"}

deep_copy마샬링 될 수있는 모든 개체에 적용됩니다. 대부분의 기본 제공 데이터 형식 (Array, Hash, String 등)을 마샬링 할 수 있습니다.

Marshalling 은 루비의 직렬화 이름입니다 . 마샬링을 사용하면 객체가 참조하는 객체가 일련의 바이트로 변환됩니다. 그런 다음 해당 바이트는 원본과 같은 다른 객체를 만드는 데 사용됩니다.


답변

Rails를 사용하는 경우 다음을 수행 할 수 있습니다.

h1 = h0.deep_dup

http://apidock.com/rails/Hash/deep_dup


답변

해시는 기존 해시에서 새 해시를 만들 수 있습니다.

irb(main):009:0> h1 = {1 => 2}
=> {1=>2}
irb(main):010:0> h2 = Hash[h1]
=> {1=>2}
irb(main):011:0> h1.object_id
=> 2150233660
irb(main):012:0> h2.object_id
=> 2150205060


답변

나는 또한 Ruby의 초보자이며 해시 복제와 비슷한 문제에 직면했습니다. 다음을 사용하십시오. 나는이 방법의 속도에 대해 전혀 모른다.

copy_of_original_hash = Hash.new.merge(original_hash)


답변

에서 언급 한 바와 같이 원수 문서의 보안 고려 사항 섹션 ,

신뢰할 수없는 데이터를 역 직렬화해야하는 경우 JSON 또는 String, Array, Hash 등과 같은 단순한 ‘기본’유형 만로드 할 수있는 다른 직렬화 형식을 사용하십시오.

다음은 Ruby에서 JSON을 사용하여 복제하는 방법에 대한 예입니다.

require "json"

original = {"John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
cloned = JSON.parse(JSON.generate(original))

# Modify original hash
original["John"] << ' Sandler'
p original
#=> {"John"=>"Adams Sandler", "Thomas"=>"Jefferson", "Johny"=>"Appleseed"}

# cloned remains intact as it was deep copied
p cloned
#=> {"John"=>"Adams", "Thomas"=>"Jefferson", "Johny"=>"Appleseed"}


답변

사용 Object#clone:

h1 = h0.clone

(혼란스럽게도에 대한 문서 cloneinitialize_copy이것을 무시하는 방법 이라고 말하지만 그 방법에 대한 링크는 대신에 Hash당신을 지시합니다 replace…)