Ruby에서 <<로 해시에 키 / 값 쌍 추가


80

Ruby에서는 << :를 사용하여 기존 배열에 값을 추가 할 수 있습니다.

a = []
a << "foo"

하지만 기존 해시에 키 / 값 쌍을 추가 할 수도 있습니까?

h = {}
h << :key "bar"

나는 당신이 할 수 있다는 것을 압니다.

h[:key] = ""
h[:key] << "bar"

그러나 그것은 내가 원하는 것이 아닙니다.

감사.


20
왜 안돼 h[:key] = "bar"?
Hauleth 2011

4
작동하지 않습니다 :h[:key] << "bar"
Chris Nielsen

답변:


141

있습니다 merge!.

h = {}
h.merge!(key: "bar")
# => {:key=>"bar"}

3
나는 merge!실제로 다른 목적으로 사용되는 것처럼 단순히 새로운 키 / 값 쌍을 만드는 것으로 자격이 있다고 생각하지 않습니다 .
PericlesTheo 2013

좋은 지적. OP가 게시하지 않은 다른 요인에 따라 끝날 수도 있다고 생각합니다.
Michael Durrant 2013

1
아, 고마워. store 메소드가 비슷한 일을하는 것 같습니다. <<는 배열에 추가하는 방법을 언급했지만 해시에서 작동하는지 확인하고 싶었 기 때문에 대부분 학문적 질문이었습니다. 다시 한 번 감사드립니다.
jcarpio 2013

5
차이점은 store단순히 새 쌍을 추가하는 것입니다. 키가 이미 있는지 여부는 상관하지 않습니다. 와 merge!방법이 조금 더 만 쌍을 추가하는 것보다 않도록하지만, 중복 키 항목이 대체됩니다. 두 가지를 벤치마킹하면 store더 빠르다 는 것을 알게 될 것입니다 (특히 작은 해시에서는 사소하지만 특히)
PericlesTheo 2013

2
@jcarpio 감사합니다. 수신자 배열을 반환하는 Hash#merge!것처럼 수신자 해시를 Array#<<반환합니다. Hash#store완전히 다른 것입니다. 또한 key: "bar"인수 위치에 해시 구문 설탕 을 사용하면 이것이 표기법에 가장 가깝다고 생각했습니다. 나는 이것이 당신이 원하는 것에 더 가깝다는 것을 알았습니다.
sawa

89

해시는 본질적으로 순서가 지정되지 않았기 때문에 추가 개념이 없습니다. 그러나 1.9 이후의 루비 해시는 삽입 순서를 유지합니다. 새 키 / 값 쌍을 추가하는 방법은 다음과 같습니다.

가장 간단한 해결책은

h[:key] = "bar"

방법을 원하면 다음을 사용하십시오 store.

h.store(:key, "bar")

정말로 "삽"연산자 ( <<) 를 사용하려면 실제로 해시 값에 배열로 추가되며 키를 지정해야합니다.

h[:key] << "bar"

위의 내용은 키가있는 경우에만 작동합니다. 새 키를 추가하려면 다음과 같이 할 수있는 기본값으로 해시를 초기화해야합니다.

h = Hash.new {|h, k| h[k] = ''}
h[:key] << "bar"

당신은 당신이 작성한 방식대로 작동하는 삽 연산자를 포함하기 위해 원숭이 패치 Hash를 유혹 할 수 있습니다.

class Hash
  def <<(k,v)
    self.store(k,v)
  end
end

그러나 이것은 다른 컨텍스트에서 삽 연산자에 적용된 "구문 설탕"을 상속하지 않습니다.

h << :key, "bar" #doesn't work
h.<< :key, "bar" #works

철저한! 기여와 통찰력에 감사드립니다.
jcarpio 2013

참고로 Ruby 1.9부터 해시가 주문됩니다.
steel

1
Ruby 1.9 이상은 삽입 순서를 유지하지만 데이터 구조로서의 Hash에는 어떤 종류의 고유 순서 개념이 없습니다.
Mark Thomas

27

아니요, 키 / 값 쌍을 추가 할 수 없다고 생각합니다. 내가 아는 가장 가까운 유일한 store방법 은 방법을 사용하는 것입니다.

h = {}
h.store("key", "value")

3

아마도 Hash # merge를 원하십니까?

1.9.3p194 :015 > h={}
 => {} 
1.9.3p194 :016 > h.merge(:key => 'bar')
 => {:key=>"bar"} 
1.9.3p194 :017 > 

제자리에서 배열을 변경하려면 merge!

1.9.3p194 :016 > h.merge!(:key => 'bar')
 => {:key=>"bar"} 

merge새로운 배열을 반환하기 때문에 좋은 생각 이 아니라고 생각 합니다. 기존 해시에 새 쌍을 추가하지 않습니다.
PericlesTheo 2013

방법에 대한 merge!(즉, 기존의 배열) 대신 merge?
Michael Durrant 2013

1
merge!기술적으로는 이러한 맥락에서 작동하지만 단순히 새 쌍을 추가하는 것보다 두 개의 해시를 병합하는 데 사용해야한다고 생각합니다. 또한 벤치마킹하면 merge!보다 느립니다 store;)
PericlesTheo 2013

3

유사 그들이있다,로 merge!store치료 기존의 해시가 다르게 키 이름에 따라, 따라서 환경 설정에 영향을 미칠 것입니다. 구문 관점에서 그 외에는, merge!key: "value"구문은 밀접하게 자바 스크립트와 파이썬에 반대 일치합니다. 개인적으로 쉼표로 구분 된 키-값 쌍을 항상 싫어했습니다.

hash = {}
hash.merge!(key: "value")
hash.merge!(:key => "value")
puts hash

{:key=>"value"}

hash = {}
hash.store(:key, "value")
hash.store("key", "value")
puts hash

{:key=>"value", "key"=>"value"}

삽 작업자가 <<작동 하도록하려면 Mark Thomas 의 답변을 사용하는 것이 좋습니다.


1

비슷한 작업을해야했지만 동일한 키로 값을 추가해야했습니다. 병합 또는 업데이트를 사용할 때 동일한 키로 값을 푸시 할 수 없습니다. 그래서 해시 배열을 사용해야했습니다.

    my_hash_static = {:header =>{:company => 'xx', :usercode => 'xx', :password => 'xx',
                      :type=> 'n:n', :msgheader => from}, :body=>[]}
    my_hash_dynamic = {:mp=>{:msg=>message, :no=>phones} }        
    my_hash_full = my_hash_static[:body].push my_hash_dynamic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.