Jak dodać do istniejącego skrótu w Rubim


102

Jeśli chodzi o dodanie key => valuepary do istniejącego, zapełnionego hasha w Rubim, jestem w trakcie pracy nad początkiem Ruby Apressa i właśnie skończyłem rozdział o hashach.

Próbuję znaleźć najprostszy sposób na osiągnięcie takich samych wyników z hashami, jak w przypadku tablic:

x = [1, 2, 3, 4]
x << 5
p x

Odpowiedzi:


190

Jeśli masz hash, możesz dodać do niego elementy, odwołując się do nich za pomocą klucza:

hash = { }
hash[:a] = 'a'
hash[:a]
# => 'a'

Tutaj, podobnie jak [ ]tworzy pustą tablicę, { }utworzy pusty hash.

Tablice mają zero lub więcej elementów w określonej kolejności, w której elementy mogą być zduplikowane. Hashe mają zero lub więcej elementów zorganizowanych według klucza , przy czym klucze nie mogą być zduplikowane, ale wartości przechowywane w tych pozycjach mogą być.

Hashe w Rubim są bardzo elastyczne i mogą mieć klucze niemal każdego typu, jakie możesz w niego rzucić. To sprawia, że ​​różni się od struktur słownikowych, które można znaleźć w innych językach.

Należy pamiętać, że często ważna jest specyfika klucza haszu:

hash = { :a => 'a' }

# Fetch with Symbol :a finds the right value
hash[:a]
# => 'a'

# Fetch with the String 'a' finds nothing
hash['a']
# => nil

# Assignment with the key :b adds a new entry
hash[:b] = 'Bee'

# This is then available immediately
hash[:b]
# => "Bee"

# The hash now contains both keys
hash
# => { :a => 'a', :b => 'Bee' }

Ruby on Rails nieco to myli, udostępniając HashWithIndifferentAccess, w którym będzie swobodnie konwertować między metodami adresowania Symbol i String.

Możesz także indeksować prawie wszystko, w tym klasy, liczby lub inne skróty.

hash = { Object => true, Hash => false }

hash[Object]
# => true

hash[Hash]
# => false

hash[Array]
# => nil

Hashe można konwertować na tablice i odwrotnie:

# Like many things, Hash supports .to_a
{ :a => 'a' }.to_a
# => [[:a, "a"]]

# Hash also has a handy Hash[] method to create new hashes from arrays
Hash[[[:a, "a"]]]
# => {:a=>"a"} 

Jeśli chodzi o „wstawianie” rzeczy do skrótu, możesz to robić pojedynczo lub użyć mergemetody łączenia skrótów:

{ :a => 'a' }.merge(:b => 'b')
# {:a=>'a',:b=>'b'}

Zauważ, że nie zmienia to pierwotnego skrótu, ale zamiast tego zwraca nowy. Jeśli chcesz połączyć jeden hash w inny, możesz użyć merge!metody:

hash = { :a => 'a' }

# Returns the result of hash combined with a new hash, but does not alter
# the original hash.
hash.merge(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Nothing has been altered in the original
hash
# => {:a=>'a'}

# Combine the two hashes and store the result in the original
hash.merge!(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Hash has now been altered
hash
# => {:a=>'a',:b=>'b'}

Podobnie jak wiele metod w String i Array, the !wskazuje, że jest to operacja w miejscu .


12
Wiele cennych informacji, ale brakuje najbardziej podstawowego sformułowania, na które po prostu odpowiada @robbrit.
danh

1
Zmień swoją odpowiedź, aby faktycznie odpowiedzieć na zadane pytanie, najlepiej gdzieś u góry. Byłoby niegrzeczne, gdybym zrobił to dla ciebie.
Stephan

@Stephan Dodano bardziej zwięzły przykład u góry.
tadman


34

Jeśli chcesz dodać więcej niż jeden:

hash = {:a => 1, :b => 2}
hash.merge! :c => 3, :d => 4
p hash

8
x = {:ca => "Canada", :us => "United States"}
x[:de] = "Germany"
p x

Próbowałem to zaimplementować w następujący sposób: x['key'] = "value"jednak otrzymuję błędy. Powinienem wspomnieć, że pracuję ze sznurkami.
Tom

1
Jaki jest błąd? Może to być wszystko, chyba że jesteś bardziej szczegółowy.
tadman

1
hash = { a: 'a', b: 'b' }
 => {:a=>"a", :b=>"b"}
hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

Zwraca scaloną wartość.

hash
 => {:a=>"a", :b=>"b"} 

Ale nie modyfikuje obiektu wywołującego

hash = hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 
hash
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

Zmiana przydziału załatwia sprawę.


0
hash {}
hash[:a] = 'a'
hash[:b] = 'b'
hash = {:a => 'a' , :b = > b}

Możesz uzyskać swój klucz i wartość z danych wejściowych użytkownika, więc możesz użyć Ruby .to_sym może przekonwertować ciąg znaków na symbol, a .to_i przekształci łańcuch w liczbę całkowitą.
Na przykład:

movies ={}
movie = gets.chomp
rating = gets.chomp
movies[movie.to_sym] = rating.to_int
# movie will convert to a symbol as a key in our hash, and 
# rating will be an integer as a value.

0

Możesz użyć operatora podwójnej ikony, który jest dostępny od Ruby 2.0:

h = { a: 1, b: 2 }
h = { **h, c: 3 }
p h
# => {:a=>1, :b=>2, :c=>3}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.