2009-11-06 10 views
6

Dla wygody próbuję przypisać wiele wartości do klawisza skrótu w Ruby. Oto kod dotychczasJak mogę przypisać wiele wartości do klawisza skrótu?

myhash = { :name => ["Tom" , "Dick" , "Harry"] } 

Przelotowe mieszania daje konkatenacyjnego ciąg wartości 3

wyjściowa:

name : TomDickHarry 

Wymagane wyjściowe:

:name => "Tom" , :name => "Dick" , :name => "Harry" 

Jaki kod musi Piszę, aby uzyskać wymagane dane wyjściowe?

Odpowiedz

4

Utworzono skrót z nazwą symbolu jako kluczem i tablicą z trzema elementami jako wartością, więc aby uzyskać poszczególne elementy tablicy, należy wykonać iterację poprzez myhash[:name].

6
myhash.each_pair {|k,v| v.each {|n| puts "#{k} => #{n}"}} 
#name => Tom 
#name => Dick 
#name => Harry 

Format wyjściowy nie jest dokładnie tym, czego potrzebujesz, ale myślę, że masz pomysł.

+0

@pierr, dziękuję. Mam więcej niż 1 klucze w tym haszu i chcę iterować nad kluczami selektywnymi, ponieważ próbuję tego dokonać. Hash [* myhash.select {| k, v | [: name] .include? (k)}. flatten], ale pojawia się błąd, co robię źle? –

+0

Powodem błędu jest to, że spłaszczanie jest rekurencyjne, więc kończy się 1 długą listą, a nie listą par kluczy i wartości. – mikej

5

Odpowiedzi Rohitha i Pierra są w tym przypadku dobre. Jeśli jednak jest to coś, z czego zamierzasz skorzystać, warto wiedzieć, że struktura danych, która zachowuje się jak skrót, ale pozwala na wiele wartości dla klucza, jest zwykle określana jako multimapa. Istnieje kilka implementacji tego dla Ruby, w tym this one.

+0

Link nie działa: http://github.com/josh/multimap – wisbucky

3

re: problem z powtarzaniem kluczy selektywnych. Spróbuj użyć reject z odwróconym warunkiem, zamiast używać select.

np. biorąc pod uwagę:

{:name=>["Tom", "Dick", "Harry"], :keep=>[4, 5, 6], :discard=>[1, 2, 3]} 

gdzie chcemy :name i :keep ale nie :discard

z select:

myhash.select { |k, v| [:name, :keep].include?(k) } 
=> [[:name, ["Tom", "Dick", "Harry"]], [:keep, [4, 5, 6]]] 

Wynikiem jest lista par.

ale z reject:

myhash.reject { |k, v| ![:name, :keep].include?(k) } 
=> {:name=>["Tom", "Dick", "Harry"], :keep=>[4, 5, 6]} 

Rezultatem jest Hash tylko wpisy, które chcesz.

ten można następnie łączyć z odpowiedzią PIERR za:

hash_to_use = myhash.reject { |k, v| ![:name, :keep].include?(k) } 
hash_to_use.each_pair {|k,v| v.each {|n| puts "#{k} => #{n}"}} 
Powiązane problemy