Un hashmap este o colecție care mapează cheile la valori. Au diferite nume în alte limbi – Python se referă la ele ca dicționare, iar obiectele JavaScript funcționează în esență ca hashmaps.

Un hashmap poate, la fel ca multe colecții, să fie construit în două moduri. Există funcția constructor:

;; Note that each argument is *prepended* to the hashmap, not appended.
(def a-hashmap (hash-map :a 1 :b 2 :c 3))
a-hashmap
; => {:c 3, :b 2, :a 1}

De asemenea, le puteți defini folosind un literal hashmap. Acest lucru este adesea mai concis și mai clar. Se recomandă utilizarea virgulelor pentru a separa perechile cheie / valoare în hashmaps, deoarece poate face limitele mai clare.

;; This hashmap is actually in the right order, unlike the one above.
(def another-hashmap {:a 1, :b 2, :c 3})
another-hashmap
; => {:a 1, :b 2, :c 3}

Când se folosește un hashmap?

Un hashmap este util atunci când doriți să dați nume variabilelor dvs. Dacă te gândești vreodată la tine, „Și dacă aș folosi un obiect …” înainte de a ieși din el și de a-ți da seama că folosești Clojure, încearcă să folosești un hashmap.

Sunt utile și dacă doriți să asociați două valori diferite. Luați, de exemplu, un cifru ROT13 – ați putea asocia A cu N, B cu M, si asa mai departe.

Acest lucru ar fi lung și plictisitor să scrii în majoritatea limbilor, dar Clojure are câteva funcții care îl pot genera și o pot face distracţie!

Cuvinte cheie și recuperarea valorilor din hashmaps

Rezistați. Ce este asta? :a? :b? :c? Acestea par ciudate. Vedeți, acestea sunt cuvinte cheie. Sunt chemați cheie-cuvinte deoarece sunt adesea folosite ca chei în hashmaps.

De ce sunt adesea folosite ca chei? Ei bine, spre deosebire de șiruri, cuvintele cheie pot fi utilizate ca funcții pentru a extrage valori dintr-un hashmap; nu este nevoie de get sau nth!

(def string-hashmap {"a" 1, "b" 2, "c" 3})
("a" string-hashmap)
; => ClassCastException java.lang.String cannot be cast to clojure.lang.IFn

(def keyword-hashmap {:a 1, :b 2, :c 3})
(:a keyword-hashmap)
; => 1

;; You can also pass a keyword a default value in case it's not found, just like get.
(:not-in-the-hashmap keyword-hashmap "not found!")
; => "not found!"

Actualizați un hashmap

Puteți actualiza valorile dintr-un hashmap folosind assoc. Acest lucru vă permite să adăugați noi perechi cheie / valoare sau să modificați altele vechi.

(def outdated-hashmap {:a 1, :b 2, :c 3})

(def newer-hashmap (assoc outdated-hashmap :d 4))
newer-hashmap
; => {:a 1, :b 2, :c 3, :d 4}

(def newest-hashmap (assoc newer-hashmap :a 22))
newest-hashmap
; => {:a 22, :b 2, :c 3, :d 4}

;; Note that outdated-hashmap has not been mutated by any of this.
;; Assoc is pure and functional.
outdated-hashmap
; => {:a 1, :b 2, :c 3}

Conversia altor colecții în hashmaps

Conversia la un hashmap este dificilă. Pentru a demonstra, să încercăm să-l folosim ca vec sau seq.

(hash-map [:a 1 :b 2 :c 3])
; => IllegalArgumentException No value supplied for key: [:a 1 :b 2 :c 3]

hash-map funcția crede că încercăm să creăm un hashmap cu [:a 1 :b 2 :c 3] ca una dintre chei. Urmăriți ce se întâmplă dacă îi oferim numărul corect de argumente:

(hash-map [:a 1 :b 2 :c 3] "foo")
; => {[:a 1 :b 2 :c 3] "foo"}

Pentru a converti o secvență într-un hashmap, va trebui să utilizați și să înțelegeți apply. Din fericire, acest lucru este destul de simplu: apply distruge în esență o colecție înainte de a-i aplica o funcție.

;; These two expressions are exactly the same.
(+ 1 2 3)
; => 6
(apply + [1 2 3])
; => 6

Acesta este modul în care ați converti un vector într-un hashmap:

(apply hash-map [:a 1 :b 2 :c 3])
; => {:c 3, :b 2, :a 1}

;; This is the same as:
(hash-map :a 1 :b 2 :c 3)
; => {:c 3, :b 2, :a 1}

Ar trebui să fie tot ceea ce aveți nevoie pentru a începe cu hashmaps în Clojure. Acum ieșiți acolo și începeți să faceți hashing cu cei mai buni dintre ei.