Liking cljdoc? Tell your friends :D

fn-in.core

This namespace provides functions to:

  • inspect an element (get)
  • change an element (assoc)
  • apply a function to an element (update)
  • remove an element (dissoc)

from any of Clojure's collection types (plus non-terminating sequences), similarly to their clojure.core namesakes. The ...-in variants operate on any heterogeneous, arbitrarily-nested data structure.

  • Elements contained in vectors, lists, and other sequences are addressed by zero-indexed integers.
  • Elements contained in maps are addressed by key, which may be any valid Clojure value, including a composite.
  • Elements contained in sets are addressed by the element's value, which may be a composite.

Conventions:

  • c collection
  • i index/key
  • x value
  • f function
  • arg1, arg2, arg3 optional args to multi-arity function f.
This namespace provides functions to:

* inspect an element (`get`)
* change an element (`assoc`)
* apply a function to an element (`update`)
* remove an element (`dissoc`)

from **any** of Clojure's collection types (plus non-terminating sequences),
similarly to their `clojure.core` namesakes. The `...-in` variants operate on
any heterogeneous, arbitrarily-nested data structure.

* Elements contained in vectors, lists, and other sequences are addressed by
  zero-indexed integers.
* Elements contained in maps are addressed by key, which may be any valid
  Clojure value, including a composite.
* Elements contained in sets are addressed by the element's value, which may
  be a composite.

Conventions:

* `c` collection
* `i` index/key
* `x` value
* `f` function
* `arg1`, `arg2`, `arg3` optional args to multi-arity function `f`.
raw docstring

assoc*cljmultimethod

(assoc* c i val)

Returns a new collection c with the key/index i associated with the supplied value val. Similar to clojure.core/assoc , but operates on all Clojure collections. Indexes beyond the end of a sequence are padded with nil.

Note: Because set members are addressed by their value, the assoc*-ed value may match a pre-existing set member, and the returned set may have one fewer members.

Examples:

(assoc* [11 22 33] 1 99) ;; => [11 99 33]
(assoc* {:a 11 :b 22} :b 99) ;; => {:a 11, :b 99}
(assoc* (list 11 22 33) 1 99) ;; => (11 99 33)
(assoc* #{11 22 33} 22 99) ;; => #{99 33 11}
(assoc* (range 3) 1 99) ;; => (0 99 2)
(assoc* (take 6 (iterate dec 10)) 3 99) ;; => (10 9 8 99 6 5)

;; associating an existing set member reduces the size of the set
(assoc* #{11 22 33} 22 33) ;; => #{33 11}

;; associating a value into a non-terminating sequence
(take 5 (assoc* (repeat 3) 2 99)) ;; => (3 3 99 3 3)

;; associating a value beyond a sequence's bounds causes nil-padding
(assoc* [11 22 33] 5 99) ;; => (11 22 33 nil nil 99)
`(assoc* c i val)`

Returns a new collection `c` with the key/index `i` associated with the
supplied value `val`. Similar to
[`clojure.core/assoc`](https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/assoc)
, but operates on all Clojure collections. Indexes beyond the end of a
sequence are padded with `nil`.

Note: Because set members are addressed by their value, the `assoc*`-ed value
may match a pre-existing set member, and the returned set may have one fewer
members.

Examples:
```clojure
(assoc* [11 22 33] 1 99) ;; => [11 99 33]
(assoc* {:a 11 :b 22} :b 99) ;; => {:a 11, :b 99}
(assoc* (list 11 22 33) 1 99) ;; => (11 99 33)
(assoc* #{11 22 33} 22 99) ;; => #{99 33 11}
(assoc* (range 3) 1 99) ;; => (0 99 2)
(assoc* (take 6 (iterate dec 10)) 3 99) ;; => (10 9 8 99 6 5)

;; associating an existing set member reduces the size of the set
(assoc* #{11 22 33} 22 33) ;; => #{33 11}

;; associating a value into a non-terminating sequence
(take 5 (assoc* (repeat 3) 2 99)) ;; => (3 3 99 3 3)

;; associating a value beyond a sequence's bounds causes nil-padding
(assoc* [11 22 33] 5 99) ;; => (11 22 33 nil nil 99)
```
sourceraw docstring

assoc-in*clj

(assoc-in* c [i & i_s] x)

Returns collection c with a new value x associated at path vector of i elements. Similar to clojure.core/assoc-in , but operates on any heterogeneous, arbitrarily-nested collections. Supplying an empty path throws an exception. Associating beyond the end of sequence results in nil-padding.

Examples:

(assoc-in* [11 22 33 [44 55 [66 77]]] [3 2 1] :foo) ;; => [11 22 33 [44 55 [66 :foo]]]
(assoc-in* {:a {:b {:c 42}}} [:a :b :c] 99) ;; => {:a {:b {:c 99}}}
(assoc-in* (list 11 22 [33 44 (list 55)]) [2 1] :foo) ;; => (11 22 [33 :foo (55)])
(assoc-in* #{11 [22 #{33}]} [[22 #{33}] 1 33] :hello) ;; => #{11 [22 #{:hello}]}

;; heterogeneous, nested collections
(assoc-in* [11 {:a [22 {:b 33}]}] [1 :a 1 :b] 42) ;; => [11 {:a [22 {:b 42}]}]
(assoc-in* {'foo (list 11 {22/7 'baz})} ['foo 1 22/7] :new-val) ;; => {foo (11 {22/7 :new-val})}

;; associating beyond nested sequence's bounds causes nil-padding
(assoc-in* [11 22 [33 44]] [2 3] 99) ;; => [11 22 (33 44 nil 99)]

;; associating a non-existent key-val in a map merely expands the map
(assoc-in* {:a 11 :b {:c 22}} [:b :d] 99) ;; => {:a 11, :b {:c 22, :d 99}}
Returns collection `c` with a new value `x` associated at path vector of
`i` elements. Similar to [`clojure.core/assoc-in`](https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/assoc-in)
, but operates on any heterogeneous, arbitrarily-nested collections. Supplying
an empty path throws an exception. Associating beyond the end of sequence
results in `nil`-padding.

Examples:
```clojure
(assoc-in* [11 22 33 [44 55 [66 77]]] [3 2 1] :foo) ;; => [11 22 33 [44 55 [66 :foo]]]
(assoc-in* {:a {:b {:c 42}}} [:a :b :c] 99) ;; => {:a {:b {:c 99}}}
(assoc-in* (list 11 22 [33 44 (list 55)]) [2 1] :foo) ;; => (11 22 [33 :foo (55)])
(assoc-in* #{11 [22 #{33}]} [[22 #{33}] 1 33] :hello) ;; => #{11 [22 #{:hello}]}

;; heterogeneous, nested collections
(assoc-in* [11 {:a [22 {:b 33}]}] [1 :a 1 :b] 42) ;; => [11 {:a [22 {:b 42}]}]
(assoc-in* {'foo (list 11 {22/7 'baz})} ['foo 1 22/7] :new-val) ;; => {foo (11 {22/7 :new-val})}

;; associating beyond nested sequence's bounds causes nil-padding
(assoc-in* [11 22 [33 44]] [2 3] 99) ;; => [11 22 (33 44 nil 99)]

;; associating a non-existent key-val in a map merely expands the map
(assoc-in* {:a 11 :b {:c 22}} [:b :d] 99) ;; => {:a 11, :b {:c 22, :d 99}}
```
sourceraw docstring

dissoc*cljmultimethod

(dissoc* c i)

Returns a new collection c with the value located at key/index i removed. Similar to clojure.core/dissoc , but operates on all Clojure collections. i must be within the bounds of a a sequence. If element at i does not exist in a map or set, the new returned collection is identical. Similarly, dissoc-ing an element from a clojure.lang.Repeat returns an indistinguishable sequence.

Examples:

(dissoc* [11 22 33] 1) ;; => [11 33]
(dissoc* {:a 11 :b 22} :a) ;; => {:b 22}
(dissoc* (list 11 22 33) 1) ;; => (11 33)
(dissoc* #{11 22 33} 22) ;; => #{33 11}
(dissoc* (take 3 (cycle [:a :b :c])) 1) ;; => (:a :c)

;; non-existent entity
(dissoc* #{11 22 33} 99) ;; => #{33 22 11}
(dissoc* {:a 11 :b 22} :c) ;; => {:a 11, :b 22}
`(dissoc* c i)`

Returns a new collection `c` with the value located at key/index `i` removed.
Similar to
[`clojure.core/dissoc`](https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/dissoc)
, but operates on all Clojure collections. `i` must be within the bounds of a
a sequence. If element at `i` does not exist in a map or set, the new returned
collection is identical. Similarly, `dissoc`-ing an element from a
`clojure.lang.Repeat` returns an indistinguishable sequence.

Examples:
```clojure
(dissoc* [11 22 33] 1) ;; => [11 33]
(dissoc* {:a 11 :b 22} :a) ;; => {:b 22}
(dissoc* (list 11 22 33) 1) ;; => (11 33)
(dissoc* #{11 22 33} 22) ;; => #{33 11}
(dissoc* (take 3 (cycle [:a :b :c])) 1) ;; => (:a :c)

;; non-existent entity
(dissoc* #{11 22 33} 99) ;; => #{33 22 11}
(dissoc* {:a 11 :b 22} :c) ;; => {:a 11, :b 22}
```
sourceraw docstring

dissoc-in*clj

(dissoc-in* c [i & i_s])

Remove element located at i from an arbitrarily-nested collection c. Any containing collections are preserved if i addresses a single scalar. If i addresses a nested collection, all children are removed.

Examples:

(dissoc-in* [11 [22 [33 44]]] [1 1 0]) ;; => [11 [22 [44]]]
(dissoc-in* {:a 11 :b {:c 22 :d 33}} [:b :c]) ;; => {:a 11, :b {:d 33}}
(dissoc-in* (list 11 (list 22 33)) [1 0]) ;; => (11 (33))
(dissoc-in* #{11 [22 33]} [[22 33] 0]) ;; => #{[33] 11}
(dissoc-in* [11 (range 4)] [1 2]) ;; => [11 (0 1 3)]

;; heterogeneous, nested collections
(dissoc-in* [11 {:a (list 22 [33 44])}] [1 :a 1 0]) ;; => [11 {:a (22 [44])}]
(dissoc-in* {:a 11 :b [22 #{33 44}]} [:b 1 33]) ;; => {:a 11, :b [22 #{44}]}

;; dissociating an element that is itself a nested collection; containers are dissociated
(dissoc-in* [11 [22]] [1]) ;; => [11]
(dissoc-in* {:a {:b {:c 99}}} [:a :b]) ;; => {:a {}}

;; dissociating a scalar element; containers are preserved
(dissoc-in* [11 [22 [33]]] [1 1 0]) ;; => [11 [22 []]]
(dissoc-in* [11 {:a 22}] [1 :a]) ;; => [11 {}]
(dissoc-in* [11 22 #{33}] [2 33]) ;; => [1 2 #{}]

See also:

Remove element located at `i` from an arbitrarily-nested collection `c`. Any
containing collections are preserved if `i` addresses a single scalar. If `i`
addresses a nested collection, all children are removed.

Examples:
```clojure
(dissoc-in* [11 [22 [33 44]]] [1 1 0]) ;; => [11 [22 [44]]]
(dissoc-in* {:a 11 :b {:c 22 :d 33}} [:b :c]) ;; => {:a 11, :b {:d 33}}
(dissoc-in* (list 11 (list 22 33)) [1 0]) ;; => (11 (33))
(dissoc-in* #{11 [22 33]} [[22 33] 0]) ;; => #{[33] 11}
(dissoc-in* [11 (range 4)] [1 2]) ;; => [11 (0 1 3)]

;; heterogeneous, nested collections
(dissoc-in* [11 {:a (list 22 [33 44])}] [1 :a 1 0]) ;; => [11 {:a (22 [44])}]
(dissoc-in* {:a 11 :b [22 #{33 44}]} [:b 1 33]) ;; => {:a 11, :b [22 #{44}]}

;; dissociating an element that is itself a nested collection; containers are dissociated
(dissoc-in* [11 [22]] [1]) ;; => [11]
(dissoc-in* {:a {:b {:c 99}}} [:a :b]) ;; => {:a {}}

;; dissociating a scalar element; containers are preserved
(dissoc-in* [11 [22 [33]]] [1 1 0]) ;; => [11 [22 []]]
(dissoc-in* [11 {:a 22}] [1 :a]) ;; => [11 {}]
(dissoc-in* [11 22 #{33}] [2 33]) ;; => [1 2 #{}]
```

See also:

* [`clojure.core.incubator/dissoc-in`](https://github.com/clojure/core.incubator/blob/4f31a7e176fcf4cc2be65589be113fc082243f5b/src/main/clojure/clojure/core/incubator.clj#L63-L75)
* [`taoensso.encore/dissoc-in`](https://taoensso.github.io/encore/taoensso.encore.html#var-dissoc-in)
* [`clj-http.client/dissoc-in`](https://cljdoc.org/d/clj-http/clj-http/3.13.0/api/clj-http.client?q=dissoc#dissoc-in)
* [`medley.core/dissoc-in`](https://weavejester.github.io/medley/medley.core.html#var-dissoc-in)
* [`plumbing.core/dissoc-in`](http://plumatic.github.io/plumbing/plumbing.core.html#var-dissoc-in)
sourceraw docstring

get*cljmultimethod

(get* c i)

Inspect the value at location i within a collection c. Similar to clojure.core/get . Returns nil if not found.

Note: get* does not offer a not-found arity.

Examples:

(get* [11 22 33 44 55] 2) ;; => 33
(get* {:x 11 :y 22 :z 33} :y) ;; => 22
(get* (list 11 22 33 44 55) 2) ;; => 33
(get* #{11 22 33} 22) ;; => 22
(get* (range 99) 3) ;; => 3
(get* (cycle [11 22 33]) 5) ;; => 33

;; non-keyword key
(get* {[11 22 33] 'val-1 99 'val-2} 99) ;; => val-2
`(get* c i)`

Inspect the value at location `i` within a collection `c`. Similar to
[`clojure.core/get`](https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/get)
. Returns `nil` if not found.

Note: `get*` does not offer a `not-found` arity.

Examples:
```clojure
(get* [11 22 33 44 55] 2) ;; => 33
(get* {:x 11 :y 22 :z 33} :y) ;; => 22
(get* (list 11 22 33 44 55) 2) ;; => 33
(get* #{11 22 33} 22) ;; => 22
(get* (range 99) 3) ;; => 3
(get* (cycle [11 22 33]) 5) ;; => 33

;; non-keyword key
(get* {[11 22 33] 'val-1 99 'val-2} 99) ;; => val-2
```
sourceraw docstring

get-in*clj

(get-in* c path)

Inspects the value in heterogeneous, arbitrarily-nested collection c at path, a vector of indexes/keys. This version of clojure.core/get-in operates on all Clojure collections. An empty path vector returns the original collection c. Performance is not optimized, so it might steal your lunch money.

Examples:

(get-in* [11 22 33 [44 [55]]] [3 1 0]) ;; => 55
(get-in* {:a 11 :b {:c 22 :d {:e 33}}} [:b :d :e]) ;; => 33
(get-in* (list 11 22 [33 (list 44 (list 55))]) [2 1 1 0]) ;; => 55
(get-in* #{11 [22 [33]]} [[22 [33]] 1 0]) ;; => 33

;; empty path addresses root collection
(get-in* [11 22 33] []) ;; => [11 22 33]

;; heterogeneous, nested collections; return may be a collection
(get-in* {:a [11 22 {:b [33 [44] 55 [66]]}]} [:a 2 :b 3]) ;; => [66]

;; address of a nested set; compare to next example
(get-in* [11 {:a [22 #{33}]}] [1 :a 1   ]) ;; => #{33}

;; address of an element contained within a nested set; compare to previous example
(get-in* [11 {:a [22 #{33}]}] [1 :a 1 33]) ;; => 33

;; non-terminating sequence
(get-in* (repeat [11 22 33]) [3 1]) ;; => 22

;; nested non-terminating sequences
(get-in* (repeat (cycle [:a :b :c])) [99 5]) ;; => :c
Inspects the value in heterogeneous, arbitrarily-nested collection `c` at
`path`, a vector of indexes/keys. This version of
[`clojure.core/get-in`](https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/get-in)
operates on all Clojure collections. An empty `path` vector returns the
original collection `c`. Performance is not optimized, so it might steal your
lunch money.

Examples:
```clojure
(get-in* [11 22 33 [44 [55]]] [3 1 0]) ;; => 55
(get-in* {:a 11 :b {:c 22 :d {:e 33}}} [:b :d :e]) ;; => 33
(get-in* (list 11 22 [33 (list 44 (list 55))]) [2 1 1 0]) ;; => 55
(get-in* #{11 [22 [33]]} [[22 [33]] 1 0]) ;; => 33

;; empty path addresses root collection
(get-in* [11 22 33] []) ;; => [11 22 33]

;; heterogeneous, nested collections; return may be a collection
(get-in* {:a [11 22 {:b [33 [44] 55 [66]]}]} [:a 2 :b 3]) ;; => [66]

;; address of a nested set; compare to next example
(get-in* [11 {:a [22 #{33}]}] [1 :a 1   ]) ;; => #{33}

;; address of an element contained within a nested set; compare to previous example
(get-in* [11 {:a [22 #{33}]}] [1 :a 1 33]) ;; => 33

;; non-terminating sequence
(get-in* (repeat [11 22 33]) [3 1]) ;; => 22

;; nested non-terminating sequences
(get-in* (repeat (cycle [:a :b :c])) [99 5]) ;; => :c
```
sourceraw docstring

update*clj

(update* c i f)
(update* c i f arg1)
(update* c i f arg1 arg2)
(update* c i f arg1 arg2 arg3)
(update* c i f arg1 arg2 arg3 & more)

Returns a new collection c with function f applied to the value at location i. If the location doesn't exist, nil is passed to f. Additional arguments args may be supplied trailing f. Similar to clojure.core/update , but operates on all Clojure collections.

Note: Because set members are addressed by their value, the update*-ed value may match a pre-existing set member, and the returned set may have one fewer members.

Examples:

(update* [10 20 30] 1 dec) ;; => [10 19 30]
(update* {:a 10} :a dec) ;; => {:a 9}
(update* (list 10 20 30) 1 dec) ;; => (10 19 30)
(update* #{10 20 30} 20 dec) ;; => #{19 30 10}

;; function handles nil if no value exists
(update* [11 22 33] 4 (constantly :updated-val)) ;; => (11 22 33 nil :updated-val)

;; additional args
(update* {:a 99} :a #(/ %1 %2) 9) ;; => {:a 11}

;; update absorbs existing set member resulting in a smaller set
(update* #{32 33} 33 dec) ;; => #{32}
Returns a new collection `c` with function `f` applied to the value at
location `i`. If the location doesn't exist, `nil`
is passed to `f`. Additional arguments `args` may be supplied trailing `f`.
Similar to [`clojure.core/update`](https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/update)
, but operates on all Clojure collections.

Note: Because set members are addressed by their value, the `update*`-ed value
may match a pre-existing set member, and the returned set may have one fewer
members.

Examples:
```clojure
(update* [10 20 30] 1 dec) ;; => [10 19 30]
(update* {:a 10} :a dec) ;; => {:a 9}
(update* (list 10 20 30) 1 dec) ;; => (10 19 30)
(update* #{10 20 30} 20 dec) ;; => #{19 30 10}

;; function handles nil if no value exists
(update* [11 22 33] 4 (constantly :updated-val)) ;; => (11 22 33 nil :updated-val)

;; additional args
(update* {:a 99} :a #(/ %1 %2) 9) ;; => {:a 11}

;; update absorbs existing set member resulting in a smaller set
(update* #{32 33} 33 dec) ;; => #{32}
```
sourceraw docstring

update-in*clj

(update-in* m ks f & args)

Returns a new collection c with the value at path vector ks updated by applying function f to the previous value. Similar to clojure.core/update-in , but operates on any heterogeneous, arbitrarily-nested collection. Additional arguments args may be supplied trailing f. If location ks does not exist, f must handle nil.

Note: Updating a set member to another previously-existing set member will decrease the size of the set.

Examples:

(update-in* [11 [22 [33]]] [1 1 0] inc) ;; => [11 [22 [34]]]
(update-in* {:a {:b {:c 99}}} [:a :b :c] inc) ;; => {:a {:b {:c 100}}}
(update-in* (list 11 [22 (list 33)]) [1 1 0] inc) ;; => (11 [22 (34)])
(update-in* #{11 [22 #{33}]} [[22 #{33}] 1 33] inc) ;; => #{[22 #{34}] 11}

;; heterogeneous nested collections
(update-in* [11 {:a 22 :b (list 33 44)}] [1 :b 1] inc) ;; => [11 {:a 22, :b (33 45)}]
(update-in* {:a [11 #{22}]} [:a 1 22] #(* % 2)) ;; => {:a [11 #{44}]}

;; beyond end of sequence
(+ nil) ;; => nil
(update-in* [11 22 33] [3] +) ;; => (11 22 33 nil)

;; non-existent key-val
(not nil) ;; => true
(update-in* {:a {:b 11}} [:a :c] not) ;; => {:a {:b 11, :c true}}

;; updating a set member to an existing value
(update-in* #{11 12} [11] inc) ;; => #{12}

;; additional args
(update-in* [11 [22 [99]]] [1 1 0] #(/ %1 %2) 3) ;; => [11 [22 [33]]]
Returns a new collection `c` with the value at path vector `ks` updated by
applying function `f` to the previous value. Similar to
[`clojure.core/update-in`](https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/update-in)
, but operates on any heterogeneous, arbitrarily-nested collection. Additional
arguments `args` may be supplied trailing `f`. If location `ks` does not exist,
`f` must handle `nil`.

Note: Updating a set member to another previously-existing set member will
decrease the size of the set.

Examples:
```clojure
(update-in* [11 [22 [33]]] [1 1 0] inc) ;; => [11 [22 [34]]]
(update-in* {:a {:b {:c 99}}} [:a :b :c] inc) ;; => {:a {:b {:c 100}}}
(update-in* (list 11 [22 (list 33)]) [1 1 0] inc) ;; => (11 [22 (34)])
(update-in* #{11 [22 #{33}]} [[22 #{33}] 1 33] inc) ;; => #{[22 #{34}] 11}

;; heterogeneous nested collections
(update-in* [11 {:a 22 :b (list 33 44)}] [1 :b 1] inc) ;; => [11 {:a 22, :b (33 45)}]
(update-in* {:a [11 #{22}]} [:a 1 22] #(* % 2)) ;; => {:a [11 #{44}]}

;; beyond end of sequence
(+ nil) ;; => nil
(update-in* [11 22 33] [3] +) ;; => (11 22 33 nil)

;; non-existent key-val
(not nil) ;; => true
(update-in* {:a {:b 11}} [:a :c] not) ;; => {:a {:b 11, :c true}}

;; updating a set member to an existing value
(update-in* #{11 12} [11] inc) ;; => #{12}

;; additional args
(update-in* [11 [22 [99]]] [1 1 0] #(/ %1 %2) 3) ;; => [11 [22 [33]]]
```
sourceraw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close