Ruby Enumerables: Hashes

By | 24 gennaio 2011

Il più famoso framework basato sul linguaggio Ruby, Ruby on Rails, fa largo uso delle hash. E visto che nel nostro blog parliamo principalmente di sviluppo con Ruby on Rails mi pare giusto approfondire alcuni costrutti del linguaggio largamente utilizzati dal nostro framework di riferimento.

In questo e nei prossimi post voglio presentare in breve le caratteristiche e le proprietà di alcuni dei costrutti più utilizzati, cominciando appunto dalle hash.

Le hash, note anche come array associativi o dizionari sono strutture dati molto flessibili che permettono di associare un valore ad una chiave che non sia necessariamente un intero, come accade invece con gli array.
Un’altra caratteristica che distingue le hash dagli array è che tipicamente una hash è una struttura non ordinata.

1. Creazione ed inizializzazione

Una hash viene creata in modo molto semplice con il metodo [].
Naturalmente una hash può essere anche inizializzata con alcuni valori in fase di creazione.
Vediamo alcuni esempi:

1
2
3
4
5
6
7
8
a = Hash.[]   # Crea una nuova hash vuota
# Crea una nuova hash inizializzata
b = Hash.[]("name", "Claudio", "age", "30")
c = Hash.[]("name" => "Claudio", "age" => "30")
d = Hash["name", "Claudio", "age", "30"]
e = Hash["name" => "Claudio", "age" => "30"]
f = {"name", "Claudio", "age", "30"}
g = {"name" => "Claudio", "age" => "30"}

Tutte le hash da ag risulteranno popolate alla stessa maniera. Personalmente prediligo la sintassi dell’ultima riga, ma il risultato è assolutamente identico per ognuna delle forme presentate.

E’ possibile anche inizializzare una hash con un valore di default da ritornare al posto di nil nel caso si tenti di accedere ad una chiave inesistente.
Per fare ciò si utilizza il metodo new.

1
2
3
4
5
a = Hash.new   # Crea una nuova hash vuota
# Crea una nuova hash con default value = -1
b = Hash.new(-1)
b["test"]   # -1
b.inspect   # {}

Il valore di default può essere impostato anche dopo la creazione della hash utilizzando il metodo default=.

1
2
3
4
5
a = Hash.[]   # Crea una nuova hash vuota
a["test"]   # nil
a.default= "no value"
a["test"]   # "no value"
a.default   # "no value"

Esiste inoltre un metodo fetch che ritorna un’eccezione IndexError nel caso si acceda ad una chiave inesistente.
Il metodo fetch può essere invocato anche con un secondo parametro che agisce come valore di default oppure con un blocco di codice che genera il valore di default a runtime in caso la chiave non esista.

1
2
3
4
5
6
a = {"name" => "Claudio", "age" => 30, "city" => "Verona"}
a.fetch("surname")                      # IndexError
a.fetch("surname", "Marai")          # "Marai"
a.fetch("age", "Marai")                 # 30
a.fetch("name"){|x| x.upcase}      # "Claudio"
a.fetch("surname"){|x| x.upcase}  # "SURNAME"

2. Inserimento, modifica, cancellazione

Per aggiungere nuovi valori, accedere o modificare i valori presenti, Hash mette a disposizione i metodi [] e []= che si possono utilizzare come segue:

1
2
3
4
5
6
a = {"name" => "Claudio"}
a["name"]                  # "Claudio"
a["age"]= 30              
a["age"]                   # 30
a["age"]= 31              
a["age"]                   # 31

La cancellazione di uno specifico valore può essere effettuata con il metodo delete passando come parametro la chiave della coppia chiave-valore da rimuovere.

1
2
3
4
a = {"name" => "Claudio", "age" => 30}
a.delete("name")
a["name"]                  # nil
a["age"]                   # 30

Il metodo clear invece svuota completamente la hash rimuovendo tutte le coppie chiave-valore.

Il metodo delete_if permette di cancellare tutte le coppie che soddisfano una determinata condizione specificata in un blocco.

1
2
3
a = {"name" => "Claudio", "age" => 30, "city" => "Verona"}
a.delete_if{|key, value| key.include? "c"}
# a => {"name" => "Claudio", "age" => 30}

Infine il metodo reject agisce come delete_if ma su una copia della hash che viene ritornata dal metodo stesso.
Fondamentalmente eseguire a.reject equivale ad come eseguire a.dup.delete_if.

Questo conclude le operazioni di base sulle hash. Nel prossimo post descriverò come iterare sui valori di una hash, convertirla in array o fare altre operazioni quali merge e sort.

Category: Svliluppo Ruby Tag:, , ,

About Claudio

Claudio Marai is a co-founder of DevInterface.

After graduating in Computer Science has contributed to develop complex web applications based on Java/J2EE and desktop applications with the. NET framework for the Ministry of Justice and ultimately for the banking ambit.

The passion for web in recent years has led him to be interested in more modern frameworks such as Ruby on Rails and Django, and to a development approach based on agile methodologies such as eXtreme Programming and SCRUM.

4 thoughts on “Ruby Enumerables: Hashes

  1. Joon

    This is obviously for ruby 1.8, because f = {“name”, “Claudio”, “age”, “30″} will not work with Ruby 1.9. Another is new hash rocketless {foo:”bar”}

  2. Cyndi Bidon

    I guess you were right in relation to Ruby Enumerables: Hashes | DevInterface Blog. brbr I don’t know that absolutely everyone could look at this like this needless to say.

  3. Pingback: The Rubyist Historian: Arrays and Hashes | History in the Digital

Comments are closed.