2017-10-01 17:39:22 +00:00
It is a convention in Specter that unparameterized navigators are capitalized, whereas parameterized navigators and macros are lowercase. When writing your own navigators, you can follow this convention for consistency and readability.
2016-06-12 02:20:39 +00:00
**Note:** Many of the descriptions and a couple of the examples are lightly edited from those found on the [Codox documentation ](http://nathanmarz.github.io/specter/com.rpl.specter.html ).
2017-10-01 17:39:22 +00:00
2016-06-16 21:25:19 +00:00
<!-- markdown - toc start - Don't edit this section. Run M - x markdown - toc - generate - toc again -->
2016-06-16 21:05:38 +00:00
**Table of Contents**
- [Unparameterized Navigators ](#unparameterized-navigators )
2017-09-11 14:51:50 +00:00
- [AFTER-ELEM ](#after-elem )
2016-06-16 21:05:38 +00:00
- [ALL ](#all )
- [ATOM ](#atom )
2017-09-11 14:53:28 +00:00
- [BEFORE-ELEM ](#before-elem )
2016-06-16 21:05:38 +00:00
- [BEGINNING ](#beginning )
2016-06-16 21:25:19 +00:00
- [DISPENSE ](#dispense )
2016-06-16 21:05:38 +00:00
- [END ](#end )
- [FIRST ](#first )
2017-09-11 14:06:17 +00:00
- [INDEXED-VALS ](#indexed-vals )
2016-06-16 21:05:38 +00:00
- [LAST ](#last )
2017-09-11 13:40:29 +00:00
- [MAP-KEYS ](#map-keys )
2016-06-16 21:05:38 +00:00
- [MAP-VALS ](#map-vals )
2016-06-16 21:25:19 +00:00
- [META ](#meta )
2017-09-11 13:45:00 +00:00
- [NAME ](#name )
2017-09-11 14:01:47 +00:00
- [NAMESPACE ](#namespace )
2016-06-16 21:05:38 +00:00
- [NIL->LIST ](#nil-list )
- [NIL->SET ](#nil-set )
- [NIL->VECTOR ](#nil-vector )
2017-09-11 14:57:20 +00:00
- [NONE-ELEM ](#none-elem )
2016-06-16 21:05:38 +00:00
- [STAY ](#stay )
- [STOP ](#stop )
- [VAL ](#val )
- [Parameterized Navigators (and Functions) ](#parameterized-navigators-and-functions )
2017-09-11 15:14:31 +00:00
- [before-index ](#before-index )
2016-06-16 21:05:38 +00:00
- [codewalker ](#codewalker )
- [collect ](#collect )
- [collect-one ](#collect-one )
- [comp-paths ](#comp-paths )
2017-10-06 22:21:44 +00:00
- [compiled-select ](#compiled- )
- [compiled-select-any ](#compiled- )
- [compiled-select-first ](#compiled- )
- [compiled-select-one ](#compiled- )
- [compiled-select-one! ](#compiled- )
- [compiled-selected-any? ](#compiled- )
- [compiled-setval ](#compiled- )
- [compiled-transform ](#compiled- )
- [compiled-traverse ](#compiled- )
- [compiled-traverse-all ](#compiled- )
2016-06-16 21:05:38 +00:00
- [cond-path ](#cond-path )
- [continue-then-stay ](#continue-then-stay )
- [continuous-subseqs ](#continuous-subseqs )
2017-09-18 12:48:08 +00:00
- [eachnav ](#eachnav )
2016-06-16 21:05:38 +00:00
- [filterer ](#filterer )
- [if-path ](#if-path )
2017-09-11 14:46:16 +00:00
- [index-nav ](#index-nav )
2016-06-16 21:05:38 +00:00
- [keypath ](#keypath )
2017-09-11 15:06:45 +00:00
- [map-key ](#map-key )
2016-06-16 21:05:38 +00:00
- [multi-path ](#multi-path )
- [must ](#must )
- [nil->val ](#nil-val )
2017-09-11 14:26:45 +00:00
- [nthpath ](#nthpath )
2016-06-16 21:05:38 +00:00
- [parser ](#parser )
- [pred ](#pred )
2017-09-11 20:10:25 +00:00
- [pred= ](#pred= )
- [pred< ](#pred< )
- [pred<= ](#pred<= )
- [pred> ](#pred> )
- [pred>= ](#pred>= )
2016-06-16 21:05:38 +00:00
- [putval ](#putval )
- [not-selected? ](#not-selected )
- [selected? ](#selected )
2017-09-11 14:19:02 +00:00
- [set-elem ](#set-elem )
2016-06-16 21:05:38 +00:00
- [srange ](#srange )
- [srange-dynamic ](#srange-dynamic )
- [stay-then-continue ](#stay-then-continue )
- [submap ](#submap )
- [subselect ](#subselect )
- [subset ](#subset )
2016-07-30 14:47:31 +00:00
- [terminal ](#terminal )
- [terminal-val ](#terminal-val )
2016-06-16 21:05:38 +00:00
- [transformed ](#transformed )
2017-10-06 22:18:40 +00:00
- [traversed ](#traversed )
2016-06-16 21:05:38 +00:00
- [view ](#view )
- [walker ](#walker )
<!-- markdown - toc end -->
2016-07-30 14:47:31 +00:00
2016-06-16 21:05:38 +00:00
# Unparameterized Navigators
2017-09-11 14:51:50 +00:00
## AFTER-ELEM
`AFTER-ELEM` navigates to the 'void' element after the sequence. For transformations – if result is not `NONE` , then append that value.
```
=> (setval AFTER-ELEM 3 [1 2])
[1 2 3]
```
2016-06-16 21:05:38 +00:00
## ALL
2016-06-11 00:42:36 +00:00
2016-06-12 16:38:10 +00:00
`ALL` navigates to every element in a collection. If the collection is a map, it will navigate to each key-value pair `[key value]` .
2016-06-11 00:42:36 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (select ALL [0 1 2 3])
2016-06-11 00:42:36 +00:00
[0 1 2 3]
2016-06-11 14:55:45 +00:00
=> (select ALL (list 0 1 2 3))
2016-06-11 00:42:36 +00:00
[0 1 2 3]
2016-06-11 14:55:45 +00:00
=> (select ALL {:a :b, :c :d})
[[:a :b] [:c :d]]
=> (transform ALL identity {:a :b, :c :d})
{:a :b, :c :d}
2016-06-11 02:53:31 +00:00
```
2017-09-11 15:48:18 +00:00
`ALL` can transform to `NONE` to remove elements.
```clojure
=> (setval [ALL nil?] NONE [1 2 nil 3 nil])
[1 2 3]
```
2016-06-16 21:05:38 +00:00
## ATOM
2016-06-11 02:53:31 +00:00
`ATOM` navigates to the value of an atom.
```clojure
=> (def a (atom 0))
2016-06-11 14:55:45 +00:00
=> (select-one ATOM a)
2016-06-11 02:53:31 +00:00
0
=> (swap! a inc)
2016-06-11 14:55:45 +00:00
=> (select-one ATOM a)
2016-06-11 02:53:31 +00:00
1
2016-06-12 02:14:09 +00:00
=> (transform ATOM inc a)
=> @a
2
2016-06-11 02:53:31 +00:00
```
2017-09-11 14:53:28 +00:00
## BEFORE-ELEM
`BEFORE-ELEM` navigates to the 'void' element before the sequence. For transformations – if result is not `NONE` , then prepend that value.
```clojure
=> (setval BEFORE-ELEM 3 [1 2])
[3 1 2]
```
2016-06-16 21:05:38 +00:00
## BEGINNING
2016-06-11 02:53:31 +00:00
2016-06-12 13:23:35 +00:00
`BEGINNING` navigates to the empty subsequence before the beginning of a collection. Useful with `setval` to add values onto the beginning of a sequence.
2016-06-11 02:53:31 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (setval BEGINNING '(0 1) (range 2 7))
2016-06-11 02:53:31 +00:00
(0 1 2 3 4 5 6)
2016-06-11 14:55:45 +00:00
=> (setval BEGINNING [0 1] (range 2 7))
2016-06-11 02:53:31 +00:00
(0 1 2 3 4 5 6)
2016-06-11 14:55:45 +00:00
=> (setval BEGINNING {0 1} (range 2 7))
2016-06-11 02:53:31 +00:00
([0 1] 2 3 4 5 6)
2016-06-12 16:38:10 +00:00
=> (setval BEGINNING '(0 1) [2 3 4])
[0 1 2 3 4]
2016-06-11 14:55:45 +00:00
=> (setval BEGINNING {:foo :baz} {:foo :bar})
2016-06-11 02:53:31 +00:00
([:foo :baz] [:foo :bar])
```
2017-09-11 15:22:08 +00:00
As of Specter 1.0.0, `BEGINNING` can now work with strings. It navigates to or transforms substrings.
```clojure
=> (select-any BEGINNING "abc")
""
=> (setval BEGINNING "b" "a")
"ba"
```
2016-06-16 21:05:38 +00:00
## DISPENSE
_Added in 0.12.0_
Drops all collected values for subsequent navigation.
```clojure
=> (transform [ALL VAL] + (range 10))
(0 2 4 6 8 10 12 14 16 18)
=> (transform [ALL VAL DISPENSE] + (range 10))
(0 1 2 3 4 5 6 7 8 9)
```
## END
2016-06-11 02:53:31 +00:00
2017-09-11 20:06:24 +00:00
`END` navigates to the empty subsequence after the end of a collection. Useful with `setval` to add values onto the end of a sequence.
2016-06-11 02:53:31 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (setval END '(5 6) (range 5))
2016-06-11 02:53:31 +00:00
(0 1 2 3 4 5 6)
2016-06-11 14:55:45 +00:00
=> (setval END [5 6] (range 5))
2016-06-11 02:53:31 +00:00
(0 1 2 3 4 5 6)
2016-06-11 14:55:45 +00:00
=> (setval END {5 6} (range 5))
2016-06-11 02:53:31 +00:00
(0 1 2 3 4 [5 6])
2016-06-12 16:38:10 +00:00
=> (setval END '(5 6) [1 2 3 4])
[1 2 3 4 5 6]
2016-06-11 14:55:45 +00:00
=> (setval END {:foo :baz} {:foo :bar})
2016-06-11 02:53:31 +00:00
([:foo :bar] [:foo :baz])
```
2017-09-11 15:22:08 +00:00
As of Specter 1.0.0, `END` can now work with strings. It navigates to or transforms substrings.
```clojure
=> (select-any END "abc")
""
=> (setval END "b" "a")
"ab"
```
2016-06-16 21:05:38 +00:00
## FIRST
2016-06-11 02:53:31 +00:00
2016-06-12 13:23:35 +00:00
`FIRST` navigates to the first element of a collection. If the collection is a map, returns a key-value pair `[key value]` . If the collection is empty, navigation stops.
2016-06-11 02:53:31 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (select-one FIRST (range 5))
2016-06-11 02:53:31 +00:00
0
2016-06-11 14:55:45 +00:00
=> (select-one FIRST (sorted-map 0 :a 1 :b))
2016-06-11 02:53:31 +00:00
[0 :a]
2016-06-11 14:55:45 +00:00
=> (select-one FIRST (sorted-set 0 1 2 3))
2016-06-11 02:53:31 +00:00
0
2016-06-11 14:55:45 +00:00
=> (select-one FIRST '())
2016-06-11 02:53:31 +00:00
nil
2016-06-11 14:55:45 +00:00
=> (select FIRST '())
2016-06-11 02:53:31 +00:00
nil
```
2017-09-11 15:48:18 +00:00
`FIRST` can transform to `NONE` to remove elements.
```clojure
=> (setval FIRST NONE [:a :b :c :d :e])
[:b :c :d :e]
```
2017-09-11 15:22:08 +00:00
As of Specter 1.0.0, `FIRST` can now work with strings. It navigates to or transforms characters.
```clojure
=> (select-any FIRST "abc")
\a
=> (setval FIRST \q "abc")
"qbc"
```
2017-09-11 14:06:17 +00:00
## INDEXED-VALS
2017-09-11 14:49:29 +00:00
`INDEXED-VALS` navigates to [index elem] pairs for each element in a sequence. Transforms of index move element at that index to the new index, shifting other elements in the sequence. Indices seen during transform take into account any shifting from prior sequence elements changing indices.
2017-09-11 14:06:17 +00:00
```clojure
=> (select [INDEXED-VALS] [1 2 3 4 5])
[[0 1] [1 2] [2 3] [3 4] [4 5]]
=> (setval [INDEXED-VALS FIRST] 0 [1 2 3 4 5])
[5 4 3 2 1]
=> (setval [INDEXED-VALS FIRST] 1 [1 2 3 4 5])
[1 5 4 3 2]
```
2016-06-16 21:05:38 +00:00
## LAST
2016-06-11 02:53:31 +00:00
2016-06-12 13:23:35 +00:00
`LAST` navigates to the last element of a collection. If the collection is a map, returns a key-value pair `[key value]` . If the collection is empty, navigation stops.
2016-06-11 02:53:31 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (select-one LAST (range 5))
2016-06-11 02:53:31 +00:00
4
2016-06-11 14:55:45 +00:00
=> (select-one LAST (sorted-map 0 :a 1 :b))
2016-06-11 02:53:31 +00:00
[1 :b]
2016-06-11 14:55:45 +00:00
=> (select-one LAST (sorted-set 0 1 2 3))
2016-06-11 02:53:31 +00:00
3
2016-06-11 14:55:45 +00:00
=> (select-one LAST '())
2016-06-11 02:53:31 +00:00
nil
2016-06-11 14:55:45 +00:00
=> (select LAST '())
2016-06-11 02:53:31 +00:00
nil
```
2017-09-11 15:48:18 +00:00
`LAST` can transform to `NONE` to remove elements.
```clojure
=> (setval LAST NONE [:a :b :c :d :e])
[:a :b :c :d]
```
2017-09-11 15:22:08 +00:00
As of Specter 1.0.0, `LAST` can now work with strings. It navigates to or transforms characters.
```clojure
=> (select-any LAST "abc")
\c
=> (setval LAST "q" "abc")
"abq"
```
2017-09-11 13:40:29 +00:00
## MAP-KEYS
2017-09-11 20:06:24 +00:00
`MAP-KEYS` navigates to every key in a map. `MAP-KEYS` is more efficient than `[ALL FIRST]` .
2017-09-11 13:40:29 +00:00
```clojure
=> (select [MAP-KEYS] {:a 3 :b 4})
[:a :b]
```
2016-06-16 21:05:38 +00:00
## MAP-VALS
2016-06-11 02:53:31 +00:00
2016-06-12 13:23:35 +00:00
`MAP-VALS` navigates to every value in a map. `MAP-VALS` is more efficient than `[ALL LAST]` .
2016-06-11 02:53:31 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (select MAP-VALS {:a :b, :c :d})
2016-06-11 02:53:31 +00:00
(:b :d)
2016-06-11 14:18:59 +00:00
=> (select [MAP-VALS MAP-VALS] {:a {:b :c}, :d {:e :f}})
2016-06-11 02:53:31 +00:00
(:c :f)
```
2017-09-11 15:48:18 +00:00
`MAP-VALS` can transform to `NONE` to remove elements.
```clojure
=> (setval [MAP-VALS even?] NONE {:a 1 :b 2 :c 3 :d 4})
{:a 1 :c 3}
```
2016-06-16 21:05:38 +00:00
## META
_Added in 0.12.0_
Navigates to the metadata of the structure, or nil if
the structure has no metadata or may not contain metadata.
```clojure
=> (select-one META (with-meta {:a 0} {:meta :data}))
{:meta :data}
2017-09-11 20:06:24 +00:00
=> (meta (transform META #(assoc % :meta :datum)
2016-06-16 21:05:38 +00:00
(with-meta {:a 0} {:meta :data})))
{:meta :datum}
```
2017-09-11 13:45:00 +00:00
## NAME
2017-09-11 20:09:24 +00:00
`NAME` navigates to the name of a keyword or symbol.
2017-09-11 13:45:00 +00:00
```clojure
=> (select [NAME] :key)
["key"]
=> (select [MAP-KEYS NAME] {:a 3 :b 4 :c 5})
["a" "b" "c"]
2017-09-11 20:09:24 +00:00
=> (setval [MAP-KEYS NAME] "q" {'a/b 3 'bbb/c 4 'd 5})
{a/q 3, bbb/q 4, q 5}
2017-09-11 13:45:00 +00:00
```
2017-09-11 14:01:47 +00:00
## NAMESPACE
2017-09-11 20:09:24 +00:00
`NAMESPACE` navigates to the namespace of keywords or symbols.
2017-09-11 14:01:47 +00:00
```clojure
=> (select [ALL NAMESPACE] [::test ::fun])
["playground.specter" "playground.specter"]
=> (select [ALL NAMESPACE] [::test :fun])
["playground.specter" nil]
2017-09-11 20:09:24 +00:00
=> (setval [ALL NAMESPACE] "a" [::test :fun])
[:a/test :a/fun]
2017-09-11 14:01:47 +00:00
```
2016-06-16 21:05:38 +00:00
## NIL->LIST
2016-06-11 02:53:31 +00:00
`NIL->LIST` navigates to the empty list `'()` if the value is nil. Otherwise it stays at the current value.
```clojure
2016-06-11 14:55:45 +00:00
=> (select-one NIL->LIST nil)
2016-06-11 02:53:31 +00:00
()
2016-06-11 14:55:45 +00:00
=> (select-one NIL->LIST :foo)
2016-06-11 02:53:31 +00:00
:foo
```
2016-06-16 21:05:38 +00:00
## NIL->SET
2016-06-11 02:53:31 +00:00
`NIL->SET` navigates to the empty set `#{}` if the value is nil. Otherwise it stays at the current value.
```clojure
2016-07-04 12:15:40 +00:00
=> (select-one NIL->SET nil)
2016-06-11 02:53:31 +00:00
#{}
2016-07-04 12:15:40 +00:00
=> (select-one NIL->SET :foo)
2016-06-11 02:53:31 +00:00
:foo
```
2016-06-16 21:05:38 +00:00
## NIL->VECTOR
2016-06-11 02:53:31 +00:00
`NIL->VECTOR` navigates to the empty vector `[]` if the value is nil. Otherwise it stays at the current value.
```clojure
2016-07-04 12:15:40 +00:00
=> (select-one NIL->VECTOR nil)
2016-06-11 02:53:31 +00:00
[]
2016-07-04 12:15:40 +00:00
=> (select-one NIL->VECTOR :foo)
2016-06-11 02:53:31 +00:00
:foo
```
2017-09-11 14:57:20 +00:00
## NONE-ELEM
`NONE-ELEM` navigates to the 'void' elem in a set. For transformations - if the result is not `NONE` , then add that value to the set.
```
=> (setval NONE-ELEM 3 #{1 2})
#{1 2 3}
=> (setval NONE-ELEM 1 nil)
#{1}
```
2016-06-16 21:05:38 +00:00
## STAY
2016-06-11 02:53:31 +00:00
`STAY` stays in place. It is the no-op navigator.
```clojure
2016-06-11 14:55:45 +00:00
=> (select-one STAY :foo)
2016-06-11 02:53:31 +00:00
:foo
```
2016-06-16 21:05:38 +00:00
## STOP
2016-06-11 02:53:31 +00:00
2016-06-12 01:56:45 +00:00
`STOP` stops navigation. For transformation, returns the structure unchanged.
2016-06-11 02:53:31 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (select-one STOP :foo)
2016-06-11 02:53:31 +00:00
nil
=> (select [ALL STOP] (range 5))
[]
=> (transform [ALL STOP] inc (range 5))
(0 1 2 3 4)
```
2016-06-16 21:05:38 +00:00
## VAL
2016-06-11 17:50:45 +00:00
2017-09-11 14:49:29 +00:00
`VAL` collects the current structure.
2016-06-11 04:55:58 +00:00
2016-06-11 22:08:05 +00:00
See also [collect ](#collect ), [collect-one ](#collect-one ), and [putval ](#putval )
2016-06-11 04:55:58 +00:00
2016-06-11 17:50:45 +00:00
```clojure
=> (select [VAL ALL] (range 3))
[[(0 1 2) 0] [(0 1 2) 1] [(0 1 2) 2]]
;; Collected values are passed as initial arguments to the update fn.
=> (transform [VAL ALL] (fn [coll x] (+ x (count coll))) (range 5))
(5 6 7 8 9)
```
2016-06-16 21:05:38 +00:00
# Parameterized Navigators (and Functions)
2016-06-11 04:55:58 +00:00
2017-09-11 15:14:31 +00:00
## before-index
`(before-index index)`
Navigates to the empty space between the index and the prior index. Selects navigate to NONE.
```clojure
=> (select-any (before-index 0) [1 2 3])
:com.rpl.specter.impl/NONE
```
Transforms to non-NONE insert at the index position.
```
=> (setval (before-index 0) :a [1 2 3])
[:a 1 2 3]
=> (setval (before-index 1) NONE [1 2 3])
[1 2 3]
=> (setval (before-index 1) :a [1 2 3])
[1 :a 2 3]
=> (setval (before-index 3) :a [1 2 3])
[1 2 3 :a]
```
2016-06-16 21:05:38 +00:00
## codewalker
2016-06-11 04:55:58 +00:00
2016-06-11 17:50:45 +00:00
`(codewalker afn)`
Using clojure.walk, `codewalker` executes a depth-first search for nodes where `afn`
returns a truthy value. When `afn` returns a truthy value, `codewalker` stops
searching that branch of the tree and continues its search of the rest of the
2016-06-12 13:23:35 +00:00
data structure. `codewalker` preserves the metadata of any forms traversed.
2016-06-11 17:50:45 +00:00
See also [walker ](#walker ).
```clojure
2017-09-11 20:06:24 +00:00
=> (select (codewalker #(and (map? %) (even? (:a %))))
2016-06-11 17:50:45 +00:00
(list (with-meta {:a 2} {:foo :bar}) (with-meta {:a 1} {:foo :baz})))
({:a 2})
=> (map meta *1)
({:foo :bar})
```
2016-06-11 04:55:58 +00:00
2016-06-16 21:05:38 +00:00
## collect
2016-06-11 04:55:58 +00:00
`(collect & paths)`
2016-06-20 16:12:37 +00:00
`collect` adds the result of running `select` with the given path on the current value to the collected vals. Note that `collect` , like `select` , returns a vector containing its results. If `transform` is called, each collected value will be passed as an argument to the transforming function with the resulting value as the last argument.
2016-06-11 04:55:58 +00:00
2016-06-11 22:08:05 +00:00
See also [VAL ](#val ), [collect-one ](#collect-one ), and [putval ](#putval )
2016-06-11 04:55:58 +00:00
```clojure
=> (select-one [(collect ALL) FIRST] (range 3))
[[0 1 2] 0]
=> (select [(collect ALL) ALL] (range 3))
[[[0 1 2] 0] [[0 1 2] 1] [[0 1 2] 2]]
=> (select [(collect ALL) (collect ALL) ALL] (range 3))
[[[0 1 2] [0 1 2] 0] [[0 1 2] [0 1 2] 1] [[0 1 2] [0 1 2] 2]]
;; Add the sum of the evens to the first element of the seq
2017-09-11 20:06:24 +00:00
=> (transform [(collect ALL even?) FIRST]
2016-06-11 04:58:17 +00:00
(fn [evens first] (reduce + first evens))
(range 5))
2016-06-11 04:55:58 +00:00
(6 1 2 3 4)
;; Replace the first element of the seq with the entire seq
=> (transform [(collect ALL) FIRST] (fn [all _] all) (range 3))
([0 1 2] 1 2)
```
2016-06-16 21:05:38 +00:00
## collect-one
2016-06-11 04:55:58 +00:00
`(collect-one & paths)`
2016-06-20 16:12:37 +00:00
`collect-one` adds the result of running `select-one` with the given path on the current value to the collected vals. Note that `collect-one` , like `select-one` , returns a single result. If there is more than one result, an exception will be thrown. If `transform` is called, each collected value will be passed as an argument to the transforming function with the resulting value as the last argument.
2016-06-11 04:55:58 +00:00
2016-06-11 22:08:05 +00:00
See also [VAL ](#val ), [collect ](#collect ), and [putval ](#putval )
2016-06-11 04:55:58 +00:00
```clojure
=> (select-one [(collect-one FIRST) LAST] (range 5))
[0 4]
=> (select [(collect-one FIRST) ALL] (range 3))
[[0 0] [0 1] [0 2]]
2016-06-11 14:18:59 +00:00
=> (transform [(collect-one :b) :a] + {:a 2, :b 3})
{:a 5, :b 3}
=> (transform [(collect-one :b) (collect-one :c) :a] * {:a 3, :b 5, :c 7})
{:a 105,, :b 5 :c 7}
2016-06-11 12:37:19 +00:00
```
2016-06-16 21:05:38 +00:00
## comp-paths
2016-06-11 12:37:19 +00:00
`(comp-paths & path)`
2016-09-30 21:54:27 +00:00
Returns a compiled version of the given path for use with compiled-{select/transform/setval/etc.} functions.
2016-06-11 12:37:19 +00:00
```clojure
=> (let [my-path (comp-paths :a :b :c)]
(compiled-select-one my-path {:a {:b {:c 0}}}))
0
```
2016-06-16 21:05:38 +00:00
## compiled-*
2016-06-11 12:37:19 +00:00
2016-06-11 14:42:15 +00:00
These functions operate in the same way as their uncompiled counterparts, but they require their path to be precompiled with [comp-paths ](#comp-paths ).
2016-06-11 14:18:59 +00:00
2016-06-16 21:05:38 +00:00
## cond-path
2016-06-11 14:18:59 +00:00
`(cond-path & conds)`
Takes as arguments alternating `cond-path1 path1 cond-path2 path2...`
Tests if selecting with cond-path on the current structure returns anything.
If so, it navigates to the corresponding path.
Otherwise, it tries the next cond-path. If nothing matches, then the structure
is not selected.
The input paths may be parameterized, in which case the result of cond-path
will be parameterized in the order of which the parameterized navigators
were declared.
2016-06-11 22:08:05 +00:00
See also [if-path ](#if-path )
2016-06-11 14:18:59 +00:00
```clojure
2016-11-14 22:25:39 +00:00
=> (select [ALL (cond-path (must :a) :a (must :b) :c)] [{:a 0} {:b 1 :c 2}])
2016-06-11 14:55:45 +00:00
[0 2]
=> (select [(cond-path (must :a) :b)] {:b 1})
()
2016-06-11 14:18:59 +00:00
```
2016-06-16 21:05:38 +00:00
## continue-then-stay
2016-06-11 14:18:59 +00:00
`(continue-then-stay & path)`
Navigates to the provided path and then to the current element. This can be used
2016-06-12 13:23:35 +00:00
to implement post-order traversal.
2016-06-11 14:18:59 +00:00
2016-06-11 17:50:45 +00:00
See also [stay-then-continue ](#stay-then-continue ).
2016-06-11 14:18:59 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (select (continue-then-stay MAP-VALS) {:a 0 :b 1 :c 2})
2016-06-11 14:18:59 +00:00
(0 1 2 {:a 0, :b 1, :c 2})
```
2016-06-16 21:05:38 +00:00
## continuous-subseqs
2016-06-11 14:18:59 +00:00
`(continuous-subseqs pred)`
2016-06-12 13:23:35 +00:00
Navigates to every continuous subsequence of elements matching `pred` .
2016-06-11 14:18:59 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (select (continuous-subseqs #(< % 10)) [5 6 11 11 3 12 2 5])
2016-06-11 14:18:59 +00:00
([5 6] [3] [2 5])
2016-06-11 14:55:45 +00:00
=> (select (continuous-subseqs #(< % 10)) [12 13])
2016-06-11 14:18:59 +00:00
()
2016-06-12 01:56:45 +00:00
=> (setval (continuous-subseqs #(< % 10)) [] [3 2 5 11 12 5 20])
[11 12 20]
2016-06-11 14:18:59 +00:00
```
2017-09-18 12:48:08 +00:00
## eachnav
`(eachnav navigator)`
Turns a navigator that takes one argument into a navigator that takes many arguments and uses the same navigator with each argument. There is no performance cost to using this.
`keypath` , `must` , and `nthpath` are all implemented using eachnav, making multiple arguments possible. See their documentation here, or look at their implementation in Specter core.
2016-06-16 21:05:38 +00:00
## filterer
2016-06-11 14:18:59 +00:00
`(filterer & path)`
Navigates to a view of the current sequence that only contains elements that
match the given path. An element matches the selector path if calling select
2016-06-12 01:56:45 +00:00
on that element with the path yields anything other than an empty sequence. Returns a vector when used in a select.
2016-06-11 14:18:59 +00:00
The input path may be parameterized, in which case the result of filterer
will be parameterized in the order of which the parameterized selectors
2016-06-12 13:23:35 +00:00
were declared. Note that filterer is a function which returns a navigator. It is the arguments to filterer that can be late-bound parameterized, not filterer.
2016-06-11 14:18:59 +00:00
2016-06-12 01:56:45 +00:00
See also [subselect ](#subselect ).
2016-06-11 14:18:59 +00:00
```clojure
;; Note that clojure functions have been extended to implement the navigator protocol
2016-06-11 14:55:45 +00:00
=> (select-one (filterer even?) (range 10))
2016-06-11 14:18:59 +00:00
[0 2 4 6 8]
2016-06-11 14:55:45 +00:00
=> (select-one (filterer identity) ['() [] #{} {} "" true false nil])
2016-06-11 14:18:59 +00:00
[() [] #{} {} "" true]
```
2016-06-16 21:05:38 +00:00
## if-path
2016-06-11 14:18:59 +00:00
`(if-path cond-path then-path)`
`(if-path cond-path then-path else-path)`
Like [cond-path ](#cond-path ), but with if semantics. If no else path is supplied and cond-path is not satisfied, stops navigation.
2016-06-11 22:08:05 +00:00
See also [if-path ](#if-path )
2016-06-11 14:18:59 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (select (if-path (must :d) :a) {:a 0, :d 1})
2016-06-11 14:18:59 +00:00
(0)
2016-06-11 14:55:45 +00:00
=> (select (if-path (must :d) :a :b) {:a 0, :b 1})
2016-06-11 14:18:59 +00:00
(1)
2016-06-11 14:55:45 +00:00
=> (select (if-path (must :d) :a) {:b 0, :d 1})
2016-06-11 14:18:59 +00:00
()
;; is equivalent to
2016-06-11 14:55:45 +00:00
=> (select (if-path (must :d) :a STOP) {:b 0, :d 1})
2016-06-11 14:18:59 +00:00
()
```
2017-09-11 14:46:16 +00:00
## index-nav
Navigates to the index of the sequence if within 0 and size. Transforms move element
at that index to the new index, shifting other elements in the sequence.
`(index-nav index)`
```clojure
=> (select [(index-nav 0)] [1 2 3 4 5])
[0]
=> (select [(index-nav 7)] [1 2 3 4 5])
[]
=> (setval (index-nav 2) 0 [1 2 3 4 5])
[3 1 2 4 5]
```
2016-06-16 21:05:38 +00:00
## keypath
2016-06-11 14:18:59 +00:00
2017-09-18 13:20:51 +00:00
`(keypath & keys)`
2016-06-11 14:18:59 +00:00
2016-06-11 14:42:15 +00:00
Navigates to the specified key, navigating to nil if it does not exist. Note that this is different from stopping navigation if the key does not exist. If you want to stop navigation, use [must ](#must ).
2016-06-11 14:18:59 +00:00
2016-06-11 22:08:05 +00:00
See also [must ](#must )
2016-06-11 14:18:59 +00:00
```clojure
2016-06-11 14:55:45 +00:00
=> (select-one (keypath :a) {:a 0})
2016-06-11 14:18:59 +00:00
0
2016-06-11 14:55:45 +00:00
=> (select-one (keypath :a :b) {:a {:b 1}})
2017-06-30 16:56:45 +00:00
1
2017-01-11 13:22:47 +00:00
=> (select [ALL (keypath :a)] [{:a 0} {:b 1}])
2016-06-11 14:18:59 +00:00
[0 nil]
2016-06-11 14:42:15 +00:00
;; Does not stop navigation
=> (select [ALL (keypath :a) (nil->val :boo)] [{:a 0} {:b 1}])
[0 :boo]
```
2017-09-18 12:37:52 +00:00
`keypath` can now take multiple arguments, for concisely specifying multiple steps. It navigates to each key one after another.
```clojure
=> (select-one (keypath "out") {"out" {"in" 3}})
{"in" 3}
=> (select-one (keypath "out" "in") {"out" {"in" 3}})
3
```
2017-09-11 15:48:18 +00:00
`keypath` can transform to `NONE` to remove elements.
```clojure
=> (setval [(keypath :a)] NONE {:a 3 :b 4})
{:b 4}
```
2017-09-11 15:06:45 +00:00
## map-key
`(map-key key)`
Navigates to the given key in the map (not to the value).
```clojure
=> (select [(map-key :a)] {:a 2 :b 3})
[:a]
=> (setval [(map-key :a)] :c {:a 2 :b 3})
{:b 3, :c 2}
```
Navigates only if the key currently exists in the map.
```clojure
=> (select [(map-key :z)] {:a 2 :b 3})
[]
```
Can transform to NONE to remove the key/value pair from the map.
```clojure
=> (setval [(map-key :a)] NONE {:a 2 :b 3})
{:b 3}
```
2016-06-16 21:05:38 +00:00
## multi-path
2016-06-11 14:42:15 +00:00
`(multi-path & paths)`
2016-06-12 13:23:35 +00:00
A path that branches on multiple paths. For transforms,
2016-06-11 14:42:15 +00:00
applies updates to the paths in order.
```clojure
2016-06-11 14:55:45 +00:00
=> (select (multi-path :a :b) {:a 0, :b 1, :c 2})
2016-06-11 14:42:15 +00:00
(0 1)
2016-06-11 14:55:45 +00:00
=> (select (multi-path (filterer odd?) (filterer even?)) (range 10))
2016-06-11 14:42:15 +00:00
([1 3 5 7 9] [0 2 4 6 8])
2016-06-11 14:55:45 +00:00
=> (transform (multi-path :a :b) (fn [x] (println x) (dec x)) {:a 0, :b 1, :c 2})
2016-06-11 14:42:15 +00:00
0
1
{:a -1, :b 0, :c 2}
```
2016-06-16 21:05:38 +00:00
## must
2016-06-11 14:42:15 +00:00
2017-09-18 13:20:51 +00:00
`(must & keys)`
2016-06-11 14:42:15 +00:00
Navigates to the key only if it exists in the map. Note that must stops navigation if the key does not exist. If you do not want to stop navigation, use [keypath ](#keypath ).
2016-06-11 22:08:05 +00:00
See also [keypath ](#keypath ) and [pred ](#pred ).
2016-06-11 14:42:15 +00:00
```clojure
=> (select-one (must :a) {:a 0})
0
=> (select-one (must :a) {:b 1})
nil
2016-06-11 17:50:45 +00:00
```
2017-09-18 12:35:44 +00:00
`must` can now take multiple arguments, for concisely specifying multiple steps. It navigates to each key, one after another.
```clojure
=> (select-any (must :a) {:a {:b 2} :c 3})
{:b 2}
=> (select-any (must :a :b) {:a {:b 2} :c 3})
2
```
2017-09-11 15:48:18 +00:00
`must` can transform to `NONE` to remove elements.
```clojure
=> (setval (must :a) NONE {:a 1 :b 2})
{:b 2}
```
2016-06-16 21:05:38 +00:00
## nil->val
2016-06-11 17:50:45 +00:00
`(nil->val v)`
Navigates to the provided val if the structure is nil. Otherwise it stays
navigated at the structure.
```clojure
=> (select-one (nil->val :a) nil)
:a
=> (select-one (nil->val :a) :b)
:b
```
2017-09-11 14:26:45 +00:00
## nthpath
2017-09-18 13:20:51 +00:00
`(nthpath & indices)`
2017-09-11 14:26:45 +00:00
Navigate to the specified indices (one after another). Transform to NONE to remove the element from the sequence.
```clojure
=> (select [(nthpath 0)] [1 2 3])
[1]
=> (select [(nthpath 2)] [1 2 3])
[3]
=> (setval [(nthpath 2)] NONE [1 2 3])
[1 2]
```
2017-09-18 12:50:58 +00:00
`nthpath` can now take multiple arguments, for concisely specifying multiple steps. It navigates to each index, one after another.
```clojure
=> (select [(nthpath 0)] [1 2 3])
[1]
=> (select [(nthpath 0)] [[0 1 2] 2 3])
[[0 1 2]]
=> (select [(nthpath 0 0)] [[0 1 2] 2 3])
[0]
```
2016-06-16 21:05:38 +00:00
## parser
2016-06-11 17:50:45 +00:00
`(parser parse-fn unparse-fn)`
2017-09-11 20:06:24 +00:00
Navigate to the result of running `parse-fn` on the value. For
transforms, the transformed value then has `unparse-fn` run on
2016-06-11 17:50:45 +00:00
it to get the final value at this point.
```clojure
=> (defn parse [address] (string/split address #"@"))
=> (defn unparse [address] (string/join "@" address))
2017-09-11 20:06:24 +00:00
=> (select [ALL (parser parse unparse) #(= "gmail.com" (second %))]
2016-06-11 17:50:45 +00:00
["test@example.com" "test@gmail.com"])
[["test" "gmail.com"]]
=> (transform [ALL (parser parse unparse) #(= "gmail.com" (second %))]
(fn [[name domain]] [(str name "+spam") domain])
["test@example.com" "test@gmail.com"])
["test@example.com" "test+spam@gmail.com"]
```
2016-06-16 21:05:38 +00:00
## pred
2016-06-11 20:20:38 +00:00
`(pred apred)`
Keeps the element only if it matches the supplied predicate. This is the
late-bound parameterized version of using a function directly in a path.
2016-06-11 22:08:05 +00:00
See also [must ](#must ).
2016-06-11 20:20:38 +00:00
```clojure
=> (select [ALL (pred even?)] (range 10))
[0 2 4 6 8]
```
2017-09-11 15:43:12 +00:00
## pred=
`(pred= value)`
Keeps elements only if they equal the provided value.
See also [pred ](#pred ).
```clojure
=> (select [ALL (pred= 2)] [1 2 2 3 4 0])
[2 2]
```
## pred<
`(pred< value)`
Keeps elements only if they are less than the provided value.
```clojure
=> (select [ALL (pred< 3 ) ] [ 1 2 2 3 4 0 ] )
[1 2 2 0]
```
See also [pred ](#pred ).
## pred>
`(pred> value)`
Keeps elements only if they are greater than the provided value.
```clojure
=> (select [ALL (pred> 3)] [1 2 2 3 4 0])
[4]
```
See also [pred ](#pred ).
## pred<=
`(pred<= value)`
2017-09-11 20:06:24 +00:00
Keeps elements only if they are less than or equal to the provided value.
2017-09-11 15:43:12 +00:00
```clojure
=> (select [ALL (pred< = 3)] [1 2 2 3 4 0])
[1 2 2 3 0]
```
See also [pred ](#pred ).
## pred>=
`(pred>= value)`
2017-09-11 20:06:24 +00:00
Keeps elements only if they are greater than or equal to the provided value.
2017-09-11 15:43:12 +00:00
```clojure
=> (select [ALL (pred>= 3)] [1 2 2 3 4 0])
[3 4]
```
See also [pred ](#pred ).
2016-06-16 21:05:38 +00:00
## putval
2016-06-11 20:20:38 +00:00
`(putval val)`
Adds an external value to the collected vals. Useful when additional arguments
are required to the transform function that would otherwise require partial
application or a wrapper function.
2016-06-11 22:08:05 +00:00
See also [VAL ](#val ), [collect ](#collect ), and [collect-one ](#collect-one )
2016-06-11 20:20:38 +00:00
```clojure
;; incrementing val at path [:a :b] by 3
=> (transform [:a :b (putval 3)] + {:a {:b 0}})
{:a {:b 3}}
```
2016-06-16 21:05:38 +00:00
## not-selected?
2016-06-11 17:50:45 +00:00
`(not-selected? & path)`
Stops navigation if the path navigator finds a result. Otherwise continues with the current structure.
The input path may be parameterized, in which case the result of selected?
will be parameterized in the order of which the parameterized navigators
were declared.
2017-09-11 20:06:24 +00:00
See also [selected? ](#selected? ).
2016-06-11 17:50:45 +00:00
```clojure
=> (select [ALL (not-selected? even?)] (range 10))
[1 3 5 7 9]
=> (select [ALL (not-selected? [(must :a) even?])] [{:a 0} {:a 1} {:a 2} {:a 3}])
[{:a 1} {:a 3}]
;; Path returns [0 2], so navigation stops
=> (select-one (not-selected? [ALL (must :a) even?]) [{:a 0} {:a 1} {:a 2} {:a 3}])
nil
```
2016-06-16 21:05:38 +00:00
## selected?
2016-06-11 17:50:45 +00:00
`(selected? & path)`
Stops navigation if the path navigator fails to find a result. Otherwise continues with the current structure.
The input path may be parameterized, in which case the result of selected?
will be parameterized in the order of which the parameterized navigators
were declared.
2017-09-11 20:06:24 +00:00
See also [not-selected? ](#not-selected? ).
2016-06-11 17:50:45 +00:00
```clojure
=> (select [ALL (selected? even?)] (range 10))
[0 2 4 6 8]
=> (select [ALL (selected? [(must :a) even?])] [{:a 0} {:a 1} {:a 2} {:a 3}])
[{:a 0} {:a 2}]
;; Path returns [0 2], so selected? returns the entire structure
=> (select-one (selected? [ALL (must :a) even?]) [{:a 0} {:a 1} {:a 2} {:a 3}])
[{:a 0} {:a 1} {:a 2} {:a 3}]
```
2017-09-11 14:19:02 +00:00
## set-elem
`(set-elem element)`
Navigates to the given element in the set only if it exists in the set.
Can transform to NONE to remove the element from the set.
```clojure
=> (select [(set-elem 3)] #{3 4 5})
[3]
=> (select [(set-elem 3)] #{4 5})
[]
=> (setval [(set-elem 3)] NONE #{3 4 5})
#{4 5}
```
2016-06-16 21:05:38 +00:00
## srange
2016-06-11 17:50:45 +00:00
`(srange start end)`
Navigates to the subsequence bound by the indexes start (inclusive)
2016-06-12 13:23:35 +00:00
and end (exclusive).
2016-06-11 17:50:45 +00:00
2016-06-12 13:23:35 +00:00
See also [srange-dynamic ](#srange-dynamic ).
2016-06-11 17:50:45 +00:00
```clojure
=> (select-one (srange 2 4) (range 5))
[2 3]
=> (select-one (srange 0 10) (range 5))
IndexOutOfBoundsException
2016-06-12 01:56:45 +00:00
=> (setval (srange 2 4) [] (range 5))
(0 1 4)
2016-06-11 17:50:45 +00:00
```
2017-09-11 15:22:08 +00:00
As of Specter 1.0.0, `srange` can now work with strings. It navigates to or transforms substrings.
```clojure
=> (select-any (srange 1 3) "abcd")
"bc"
=> (setval (srange 1 3) "" "abcd")
"ad"
2017-09-11 15:48:18 +00:00
=> (setval [(srange 1 3) END] "x" "abcd")
2017-09-11 15:22:08 +00:00
"abcxd"
```
2016-06-16 21:05:38 +00:00
## srange-dynamic
2016-06-11 17:50:45 +00:00
`(srange-dynamic start-fn end-fn)`
Uses start-fn and end-fn to determine the bounds of the subsequence
2016-06-12 13:23:35 +00:00
to select when navigating. Each function takes in the structure as input.
2016-06-11 17:50:45 +00:00
See also [srange ](#srange ).
```clojure
=> (select-one (srange-dynamic #(.indexOf % 2) #(.indexOf % 4)) (range 5))
[2 3]
=> (select-one (srange-dynamic (fn [_] 0) #(quot (count %) 2)) (range 10))
[0 1 2 3 4]
```
2016-06-16 21:05:38 +00:00
## stay-then-continue
2016-06-11 17:50:45 +00:00
`(stay-then-continue)`
Navigates to the current element and then navigates via the provided path.
This can be used to implement pre-order traversal.
See also [continue-then-stay ](#continue-then-stay ).
```clojure
=> (select (stay-then-continue MAP-VALS) {:a 0 :b 1 :c 2})
({:a 0, :b 1, :c 2} 0 1 2)
```
2016-06-16 21:05:38 +00:00
## submap
2016-06-11 17:50:45 +00:00
`(submap m-keys)`
Navigates to the specified submap (using select-keys).
In a transform, that submap in the original map is changed to the new
value of the submap.
```clojure
=> (select-one (submap [:a :b]) {:a 0, :b 1, :c 2})
{:a 0, :b 1}
=> (select-one (submap [:c]) {:a 0})
{}
;; (submap [:a :c]) returns {:a 0} with no :c
=> (transform [(submap [:a :c]) MAP-VALS]
inc
{:a 0, :b 1})
{:b 1, :a 1}
;; We replace the empty submap with {:c 2} and merge with the original
;; structure
=> (transform (submap []) #(assoc % :c 2) {:a 0, :b 1})
{:a 0, :b 1, :c 2}
```
2016-06-16 21:05:38 +00:00
## subselect
2016-06-11 17:50:45 +00:00
`(subselect & path)`
Navigates to a sequence that contains the results of (select ...),
but is a view to the original structure that can be transformed.
2016-06-12 01:56:45 +00:00
Without subselect, we could only transform selected values individually.
`subselect` lets us transform them together as a seq, much like `filterer` .
2016-06-11 17:50:45 +00:00
Requires that the input navigators will walk the structure's
children in the same order when executed on "select" and then
"transform".
2016-06-12 13:23:35 +00:00
See also [filterer ](#filterer ).
2016-06-11 17:50:45 +00:00
```clojure
2016-06-12 01:56:45 +00:00
=> (transform (subselect (walker number?) even?)
reverse
[1 [[[2]] 3] 5 [6 [7 8]] 10])
[1 [[[10]] 3] 5 [8 [7 6]] 2]
2016-06-11 17:50:45 +00:00
```
2016-06-16 21:05:38 +00:00
## subset
2016-06-11 17:50:45 +00:00
`(subset aset)`
Navigates to the specified subset (by taking an intersection).
In a transform, that subset in the original set is changed to the
new value of the subset.
```clojure
=> (select-one (subset #{:a :b}) #{:b :c})
#{:b}
;; Replaces the #{:a} subset with #{:a :c} and unions back into
;; the original structure
=> (setval (subset #{:a}) #{:a :c} #{:a :b})
#{:c :b :a}
```
2016-07-30 14:47:31 +00:00
## terminal
`(terminal update-fn)`
_Added in 0.12.0_
For usage with `multi-transform` , defines an endpoint in the navigation that
will have the parameterized transform function run. The transform function works
just like it does in `transform` , with collected values given as the first
arguments.
2016-07-30 14:50:10 +00:00
See also [terminal-val ](#terminal-val ) and [multi-transform ](List-of-Macros#multi-transform ).
2016-07-30 14:47:31 +00:00
```clojure
=> (multi-transform [(putval 3) (terminal +)] 1)
4
2017-09-11 20:06:24 +00:00
=> (multi-transform [:a :b (multi-path [:c (terminal inc)]
2016-07-30 14:47:31 +00:00
[:d (putval 3) (terminal +)])]
{:a {:b {:c 42 :d 1}}})
{:a {:b {:c 43, :d 4}}}
```
## terminal-val
`(terminal-val val)`
_Added in 0.12.0_
Like `terminal` but specifies a val to set at the location regardless of
the collected values or the value at the location.
```clojure
=> (multi-transform (terminal-val 2) 3)
2
```
2016-07-30 14:50:10 +00:00
See also [terminal ](#terminal ) and [multi-transform ](List-of-Macros#multi-transform ).
2016-07-30 14:47:31 +00:00
2016-06-16 21:05:38 +00:00
## transformed
2016-06-11 17:50:45 +00:00
`(transformed path update-fn)`
Navigates to a view of the current value by transforming it with the
specified path and update-fn.
The input path may be parameterized, in which case the result of transformed
will be parameterized in the order of which the parameterized navigators
were declared.
See also [view ](#view )
```clojure
=> (select-one (transformed [ALL odd?] #(* % 2)) (range 10))
(0 2 2 6 4 10 6 14 8 18)
=> (transform [(transformed [ALL odd?] #(* % 2)) ALL] #(/ % 2) (range 10))
(0 1 1 3 2 5 3 7 4 9)
```
2017-09-11 15:34:31 +00:00
## traversed
`(traversed path reduce-fn)`
Navigates to a view of the current value by transforming with a reduction over
the specified traversal.
```clojure
=> (select-any (traversed ALL +) [1 2 3 4])
10
```
2016-06-16 21:05:38 +00:00
## view
2016-06-11 17:50:45 +00:00
`(view afn)`
Navigates to result of running `afn` on the currently navigated value.
See also [transformed ](#transformed ).
```clojure
=> (select-one [FIRST (view inc)] (range 5))
1
```
2016-06-16 21:05:38 +00:00
## walker
2016-06-11 17:50:45 +00:00
`(walker afn)`
Using clojure.walk, `walker` executes a depth-first search for nodes where `afn`
returns a truthy value. When `afn` returns a truthy value, `walker` stops
searching that branch of the tree and continues its search of the rest of the
2016-06-12 13:23:35 +00:00
data structure.
2016-06-11 17:50:45 +00:00
See also [codewalker ](#codewalker )
```clojure
2016-06-12 02:10:25 +00:00
=> (select (walker #(and (number? %) (even? %))) '(1 (3 4) 2 (6)))
2016-06-11 17:50:45 +00:00
(4 2 6)
;; Note that (3 4) and (6 7) are not returned because the search halted at
;; (2 (3 4) (5 (6 7))).
2017-09-11 20:06:24 +00:00
=> (select (walker #(and (counted? %) (even? (count %))))
2016-06-11 17:50:45 +00:00
'(1 (2 (3 4) 5 (6 7)) (8 9)))
((2 (3 4) 5 (6 7)) (8 9))
2017-09-11 20:06:24 +00:00
=> (setval (walker #(and (counted? %) (even? (count %))))
2016-06-12 02:10:25 +00:00
:double
'(1 (2 (3 4) 5 (6 7)) (8 9)))
2016-06-11 17:50:45 +00:00
(1 :double :double)
2016-06-15 17:38:47 +00:00
```