Dík za článok!
Clojure podporuje i tři složené datové typy, nad nimiž je navíc postaven abstraktní typ sekvence. Především se jedná o seznamy (list), vektory (vector), množiny (set) a mapy (map).
To sú 4. dátove typy. Myslím, že lepšie by bolo napísať niečo v zmysle:
Clojure podporuje zložené dátové typy. Zo zložených dátových typov, ktoré navyše podporujú abstraktný typ sekvencie sú najvýznamnejšie zoznamy (list), vektory (vector), množiny (set) a mapy (map).
zkusím...
mapa ... abstraktní datová struktura
Vlastně jedinou operací, kterou by mapa měla umět, je nalézt prvek podle jeho klíče. A klíčem obecně může být cokoli, nejenom celé číslo.
Mapa je abstraktním datovým typem, ale její konkrétní implementace mají i další vlastnosti, třeba to, jak se vrací dvojice klíč:hodnota při sekvenčním procházení mapou. O tom je vlastně celý článek, že se to dá dělat různě pro různé potřeby.
V některých jazycích se mapám říká slovníky, asociativní pole, hashe (heše). Ale heše neříkej na pohovoru :-) protože to je obecně špatně a asi to zavedl Perl (ten vůbec spoustu věcí v IT minimálně zkonil). Lepší by bylo říkat slovník (tak to má python), ale to zase lidem asociuje, že je to nějak setříděné (to python tedy umí, ale až od nedávna). Třeba java taky používá mapa (https://docs.oracle.com/javase/7/docs/api/java/util/Map.html). Někde jsem slyšel i použití "tabulka", ale to je dost mimo.
V Clojure, tedy pokud to chápu, jsou mapy neměnitelné, takže jejich popis je takto jednoduchý. Není nutné popisovat, jak se vkládají nebo mažou nebo přepisují prvky protože to vlastně nejde a je to tak správně :-)
PS: ale v Clojure nedělám, jen si o něm něco čtu a dívám se na videa od Riche.
Někde jsem slyšel i použití "tabulka", ale to je dost mimo
Nie je to mimo. Mapa je tabuľka s dvomi stĺpcami: kľúč a hodnota. Pozri Dispatch Table, Conversion Table.
Mapu je možné chápať aj ako lookup tabuľku, t.j. implementáciu referenčne transparentnej funkcie. Pozri memoize, kde mem
je definované ako (atomická) mapa: (let [mem (atom {})] ...)
No a do tretice, každá funkcia je reláciou, takže na mapu sa dá nazerať aj ako na reláciu.
Diky za zaujimavy a obsiahly clanok!
Par komentov:
V sekcii 10 je ukazka hash-map ktora pouziva nespravny vypis poradia hodnot v mape - to co je ukazane zodpoveda skor pouzitiu array-map, nie hash-map.
hash-map vypise kluce v poradi konzistentnom so seq, keys, a vals.
(def p1 (hash-map :a 2 :b 1 :c 3 :d 5 :e 4 :f 3 :g 0 :h 10 :i 6 :j 7))
p1
;;=> {:e 4, :g 0, :c 3, :j 7, :h 10, :b 1, :d 5, :f 3, :i 6, :a 2}
Mozno by bolo tiez dobre spomenut ze mapovy literal {} vytvara automaticka instanciu "array map" pre pocet prvkov <= 8 a "hash map" pre viacero prvkov:
(def p1a { :a 2 :b 1 :c 3 :d 5 :e 4 :f 3 :g 0 :h 10 })
p1a
;;=> {:a 2, :b 1, :c 3, :d 5, :e 4, :f 3, :g 0, :h 10}
;;;
(def p1 { :a 2 :b 1 :c 3 :d 5 :e 4 :f 3 :g 0 :h 10 :i 6})
p1
;;=> {:e 4, :g 0, :c 3, :h 10, :b 1, :d 5, :f 3, :i 6, :a 2}
Tiez je dobre podotknut ze operacia assoc "potichu" zmeni type mapy ak pocet prvkov prekroci 8:
(def p1a { :a 2 :b 1 :c 3 :d 5 :e 4 :f 3 :g 0 :h 10 })
(type p1a)
;;=> clojure.lang.PersistentArrayMap
;;;
(assoc p1a :i 6)
;;=> {:e 4, :g 0, :c 3, :h 10, :b 1, :d 5, :f 3, :i 6, :a 2}
(type (assoc p1a :i 6))
;;=> clojure.lang.PersistentHashMap
A este posledna vec:
> Pokud se do mapy ukládají i hodnoty nil, nezbývá většinou nic jiného, než kombinace get+contains?:
Pre tieto pripady je uzitocny idiom vyuzivajuci if-let a find:
(if-let [[k v] (find {:a 1 :b nil} :b)] :found :not-found)
;;=> :found
(if-let [[k v] (find {:a 1 :b nil} :c)] :found :not-found)
;;=> :not-found
Díky za doplnění. Ta info o tom, že pro malé mapy se používá PersistentArrayMap jsem chtěl uvést, ale je zajímavé, že různé verze Clojure se v tomto ohledu chovají jinak - popravdě jsem se nedíval do zdrojáků, ale ten threshold se posunul v 1.10. Nicméně v základě je to přesně tak, jak píšete - pro malé mapy se hash nedělá.