Files
CljElixir/stubs/Map.clj
2026-03-09 23:09:46 -04:00

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])