177 lines
4.6 KiB
Clojure
177 lines
4.6 KiB
Clojure
(ns Map
|
|
"Elixir Map module — operations on maps.
|
|
|
|
In CljElixir: (Map/get m :key), (Map/put m :key val), etc.
|
|
Maps are the fundamental key-value data structure on the BEAM.")
|
|
|
|
;; --- Access ---
|
|
|
|
(defn get
|
|
"Gets the value for `key` in `map`. Returns `default` if key is missing.
|
|
(Map/get {:a 1 :b 2} :a) ;=> 1
|
|
(Map/get {:a 1} :c :not-found) ;=> :not-found"
|
|
([map key])
|
|
([map key default]))
|
|
|
|
(defn get-lazy
|
|
"Gets `key` from `map`, calling `fun` for default if missing.
|
|
(Map/get-lazy m :key (fn [] (expensive-computation)))"
|
|
[map key fun])
|
|
|
|
(defn fetch
|
|
"Returns {:ok value} if `key` exists, :error otherwise.
|
|
(Map/fetch {:a 1} :a) ;=> {:ok 1}
|
|
(Map/fetch {:a 1} :b) ;=> :error"
|
|
[map key])
|
|
|
|
(defn fetch!
|
|
"Gets the value for `key`. Raises if key is missing.
|
|
(Map/fetch! {:a 1} :a) ;=> 1"
|
|
[map key])
|
|
|
|
(defn has-key?
|
|
"Returns true if `map` contains `key`.
|
|
(Map/has-key? {:a 1 :b 2} :a) ;=> true"
|
|
[map key])
|
|
|
|
(defn keys
|
|
"Returns all keys in the map.
|
|
(Map/keys {:a 1 :b 2}) ;=> [:a :b]"
|
|
[map])
|
|
|
|
(defn values
|
|
"Returns all values in the map.
|
|
(Map/values {:a 1 :b 2}) ;=> [1 2]"
|
|
[map])
|
|
|
|
;; --- Modification ---
|
|
|
|
(defn put
|
|
"Puts the given `value` under `key` in `map`.
|
|
(Map/put {:a 1} :b 2) ;=> {:a 1 :b 2}"
|
|
[map key value])
|
|
|
|
(defn put-new
|
|
"Puts `value` under `key` only if `key` doesn't exist yet.
|
|
(Map/put-new {:a 1} :a 99) ;=> {:a 1}
|
|
(Map/put-new {:a 1} :b 2) ;=> {:a 1 :b 2}"
|
|
[map key value])
|
|
|
|
(defn put-new-lazy
|
|
"Like put-new but calls `fun` only if key is absent.
|
|
(Map/put-new-lazy m :key (fn [] (expensive-computation)))"
|
|
[map key fun])
|
|
|
|
(defn delete
|
|
"Deletes `key` from `map`. No-op if key doesn't exist.
|
|
(Map/delete {:a 1 :b 2} :a) ;=> {:b 2}"
|
|
[map key])
|
|
|
|
(defn drop
|
|
"Drops the given `keys` from `map`.
|
|
(Map/drop {:a 1 :b 2 :c 3} [:a :c]) ;=> {:b 2}"
|
|
[map keys])
|
|
|
|
(defn take
|
|
"Takes only the given `keys` from `map`.
|
|
(Map/take {:a 1 :b 2 :c 3} [:a :c]) ;=> {:a 1 :c 3}"
|
|
[map keys])
|
|
|
|
(defn pop
|
|
"Returns the value for `key` and the map without `key`.
|
|
(Map/pop {:a 1 :b 2} :a) ;=> {1 {:b 2}}
|
|
(Map/pop {:a 1} :c :default) ;=> {:default {:a 1}}"
|
|
([map key])
|
|
([map key default]))
|
|
|
|
(defn pop-lazy
|
|
"Like pop but calls `fun` for default if key is absent."
|
|
[map key fun])
|
|
|
|
(defn update
|
|
"Updates the value at `key` by applying `fun` to the current value.
|
|
(Map/update {:a 1} :a (fn [v] (+ v 1))) ;=> {:a 2}"
|
|
([map key fun])
|
|
([map key default fun]))
|
|
|
|
(defn update!
|
|
"Updates `key` by applying `fun`. Raises if `key` doesn't exist.
|
|
(Map/update! {:a 1} :a (fn [v] (* v 2))) ;=> {:a 2}"
|
|
[map key fun])
|
|
|
|
(defn replace
|
|
"Replaces value at `key` only if it already exists. No-op otherwise.
|
|
(Map/replace {:a 1} :a 99) ;=> {:a 99}
|
|
(Map/replace {:a 1} :b 99) ;=> {:a 1}"
|
|
[map key value])
|
|
|
|
(defn replace!
|
|
"Replaces value at `key`. Raises if `key` doesn't exist."
|
|
[map key value])
|
|
|
|
;; --- Merging ---
|
|
|
|
(defn merge
|
|
"Merges two maps. Values from `map2` take precedence.
|
|
(Map/merge {:a 1 :b 2} {:b 3 :c 4}) ;=> {:a 1 :b 3 :c 4}
|
|
With resolver: (Map/merge m1 m2 (fn [k v1 v2] (+ v1 v2)))"
|
|
([map1 map2])
|
|
([map1 map2 resolver]))
|
|
|
|
(defn split
|
|
"Splits `map` into two maps based on the given `keys`.
|
|
(Map/split {:a 1 :b 2 :c 3} [:a :c]) ;=> {%{a: 1, c: 3} %{b: 2}}"
|
|
[map keys])
|
|
|
|
;; --- Conversion ---
|
|
|
|
(defn new
|
|
"Creates a new empty map or from an enumerable.
|
|
(Map/new) ;=> {}
|
|
(Map/new [[:a 1] [:b 2]]) ;=> {:a 1 :b 2}
|
|
(Map/new [1 2 3] (fn [x] {x (* x x)})) ;=> {1 1, 2 4, 3 9}"
|
|
([])
|
|
([enumerable])
|
|
([enumerable transform]))
|
|
|
|
(defn from-struct
|
|
"Converts a struct to a plain map (removes __struct__ key).
|
|
(Map/from-struct my-struct) ;=> {...}"
|
|
[struct])
|
|
|
|
(defn to-list
|
|
"Converts a map to a keyword list (list of {key, value} tuples).
|
|
(Map/to-list {:a 1 :b 2}) ;=> [[:a 1] [:b 2]]"
|
|
[map])
|
|
|
|
(defn equal?
|
|
"Returns true if two maps are equal.
|
|
(Map/equal? {:a 1} {:a 1}) ;=> true"
|
|
[map1 map2])
|
|
|
|
;; --- Filtering ---
|
|
|
|
(defn filter
|
|
"Filters map entries where `f` returns truthy. `f` receives {key, value}.
|
|
(Map/filter {:a 1 :b 2 :c 3} (fn [{k v}] (> v 1))) ;=> {:b 2 :c 3}"
|
|
[map f])
|
|
|
|
(defn reject
|
|
"Rejects map entries where `f` returns truthy.
|
|
(Map/reject {:a 1 :b 2 :c 3} (fn [{k v}] (> v 1))) ;=> {:a 1}"
|
|
[map f])
|
|
|
|
(defn map
|
|
"Maps over entries, `f` receives {key, value} and must return {key, value}.
|
|
(Map/map {:a 1 :b 2} (fn [{k v}] {k (* v 10)})) ;=> {:a 10 :b 20}"
|
|
[map f])
|
|
|
|
(defn intersect
|
|
"Returns entries common to both maps (using `map2` values)."
|
|
([map1 map2])
|
|
([map1 map2 resolver]))
|
|
|
|
(defn diff
|
|
"Returns {entries_only_in_map1, entries_only_in_map2, entries_in_both}."
|
|
[map1 map2])
|