W Rubim można dodawać wartości do istniejących tablic używając <<:
a = []
a << "foo"
ale czy możesz również dołączyć pary klucz / wartość do istniejącego skrótu?
h = {}
h << :key "bar"
Wiem, że potrafisz:
h[:key] = ""
h[:key] << "bar"
ale tego nie chcę.
Dzięki.
h[:key] = "bar"
?h[:key] << "bar"
Odpowiedzi:
Jest
merge!
.h = {} h.merge!(key: "bar") # => {:key=>"bar"}
źródło
merge!
kwalifikowało się to jako zwykłe utworzenie nowej pary klucz / wartość, ponieważ jest ona faktycznie używana do innego celu.store
po prostu dodaje nową parę, nie obchodzi go, czy klucz już istnieje. zemerge!
jednak wpisy z zduplikowane klucze są zastępowane więc metoda robi nieco więcej niż tylko dodanie par. Jeśli porównasz te dwa, okażestore
się , że jesteś szybszy (trywialne, ale szczególnie w przypadku małych haszów)Hash#merge!
zwraca wartość skrótu odbiornika, tak jakArray#<<
zwraca tablicę odbiornika.Hash#store
to zupełnie inna sprawa. Ponadto, z cukrem składni mieszaniakey: "bar"
w pozycji argumentu, pomyślałem, że jest to najbliższe możliwe do uzyskania notacji. Wiedziałem, że ten jest bliżej tego, czego chciałeś.Ponieważ skróty nie są z natury uporządkowane, nie istnieje pojęcie dołączania. Jednak skróty Ruby od wersji 1.9 utrzymują kolejność reklam. Oto sposoby dodawania nowych par klucz / wartość.
Najprostszym rozwiązaniem jest
h[:key] = "bar"
Jeśli chcesz metodę, użyj
store
:h.store(:key, "bar")
Jeśli naprawdę chcesz użyć operatora „łopata” (
<<
), w rzeczywistości jest on dołączany do wartości skrótu jako tablica i musisz określić klucz:h[:key] << "bar"
Powyższe działa tylko wtedy, gdy istnieje klucz. Aby dołączyć nowy klucz, musisz zainicjować skrót wartością domyślną, co możesz zrobić w następujący sposób:
h = Hash.new {|h, k| h[k] = ''} h[:key] << "bar"
Możesz ulec pokusie, aby małpa łatać Hash, aby dołączyć operatora łopaty, który działa w sposób, w jaki napisałeś:
class Hash def <<(k,v) self.store(k,v) end end
Jednak to nie dziedziczy „cukru syntaktycznego” stosowanego do operatora łopaty w innych kontekstach:
h << :key, "bar" #doesn't work h.<< :key, "bar" #works
źródło
Nie, nie sądzę, aby można było dołączać pary klucz / wartość. Jedyne, co jest mi najbliższe , to użycie
store
metody:h = {} h.store("key", "value")
źródło
Może chcesz Hash # merge?
1.9.3p194 :015 > h={} => {} 1.9.3p194 :016 > h.merge(:key => 'bar') => {:key=>"bar"} 1.9.3p194 :017 >
Jeśli chcesz zmienić tablicę w miejscu, użyj
merge!
1.9.3p194 :016 > h.merge!(:key => 'bar') => {:key=>"bar"}
źródło
merge
to nie jest dobry pomysł, ponieważ zwraca nową tablicę; nie dodawanie nowej pary do istniejącego skrótu.merge!
(tj. Do istniejącej tablicy) zamiastmerge
?merge!
technicznie działa w tym kontekście, ale myślę, że powinien być używany do łączenia dwóch skrótów, a nie po prostu dodawania nowej pary. Ponadto, jeśli porównaszmerge!
, jest wolniej niżstore
;)Są podobne
merge!
istore
traktują istniejące skróty w różny sposób w zależności od nazw kluczy, dlatego wpłyną na twoje preferencje. Inne niż to, z punktu widzenia składni,merge!
„skey: "value"
składnia zbliżony przeciwko JavaScript i Python. Osobiście zawsze nienawidziłem par klucz-wartość oddzielających przecinki.hash = {} hash.merge!(key: "value") hash.merge!(:key => "value") puts hash
hash = {} hash.store(:key, "value") hash.store("key", "value") puts hash
Aby operator łopaty
<<
działał, radziłbym skorzystać z odpowiedzi Marka Thomasa .źródło
Musiałem zrobić podobną rzecz, ale musiałem dodać wartości z tymi samymi kluczami. Kiedy używam scalania lub aktualizacji, nie mogę wypychać wartości za pomocą tych samych kluczy. Musiałem więc użyć tablicy skrótów.
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
źródło