Bahex
|
e7d2717424
|
feat(std-rfc): add iter module and recurse command (#15840)
# Description
`recurse` command is similar to `jq`'s `recurse`/`..` command. Along
with values, it also returns their cell-paths relative to the "root"
(initial input)
By default it uses breadth-first traversal, collecting child items of
all available sibling items before starting to process those child
items. This means output is ordered in increasing depth.
With the `--depth-first` flag it uses a stack based recursive descend,
which results in output order identical to `jq`'s `recurse`.
It can be used in the following ways:
- `... | recurse`: Recursively traverses the input value, returns each
value it finds as a stream.
- `... | recurse foo.bar`: Only descend through the given cell-path.
- `... | recurse {|parent| ... }`: Produce child values with a closure.
```nushell
{
"foo": {
"egg": "X"
"spam": "Y"
}
"bar": {
"quox": ["A" "B"]
}
}
| recurse
| update item { to nuon }
# => ╭───┬──────────────┬───────────────────────────────────────────────╮
# => │ # │ path │ item │
# => ├───┼──────────────┼───────────────────────────────────────────────┤
# => │ 0 │ $. │ {foo: {egg: X, spam: Y}, bar: {quox: [A, B]}} │
# => │ 1 │ $.foo │ {egg: X, spam: Y} │
# => │ 2 │ $.bar │ {quox: [A, B]} │
# => │ 3 │ $.foo.egg │ "X" │
# => │ 4 │ $.foo.spam │ "Y" │
# => │ 5 │ $.bar.quox │ [A, B] │
# => │ 6 │ $.bar.quox.0 │ "A" │
# => │ 7 │ $.bar.quox.1 │ "B" │
# => ╰───┴──────────────┴───────────────────────────────────────────────╯
{"name": "/", "children": [
{"name": "/bin", "children": [
{"name": "/bin/ls", "children": []},
{"name": "/bin/sh", "children": []}]},
{"name": "/home", "children": [
{"name": "/home/stephen", "children": [
{"name": "/home/stephen/jq", "children": []}]}]}]}
| recurse children
| get item.name
# => ╭───┬──────────────────╮
# => │ 0 │ / │
# => │ 1 │ /bin │
# => │ 2 │ /home │
# => │ 3 │ /bin/ls │
# => │ 4 │ /bin/sh │
# => │ 5 │ /home/stephen │
# => │ 6 │ /home/stephen/jq │
# => ╰───┴──────────────────╯
{"name": "/", "children": [
{"name": "/bin", "children": [
{"name": "/bin/ls", "children": []},
{"name": "/bin/sh", "children": []}]},
{"name": "/home", "children": [
{"name": "/home/stephen", "children": [
{"name": "/home/stephen/jq", "children": []}]}]}]}
| recurse children --depth-first
| get item.name
# => ╭───┬──────────────────╮
# => │ 0 │ / │
# => │ 1 │ /bin │
# => │ 2 │ /bin/ls │
# => │ 3 │ /bin/sh │
# => │ 4 │ /home │
# => │ 5 │ /home/stephen │
# => │ 6 │ /home/stephen/jq │
# => ╰───┴──────────────────╯
2
| recurse { ({path: square item: ($in * $in)}) }
| take while { $in.item < 100 }
# => ╭───┬─────────────────┬──────╮
# => │ # │ path │ item │
# => ├───┼─────────────────┼──────┤
# => │ 0 │ $. │ 2 │
# => │ 1 │ $.square │ 4 │
# => │ 2 │ $.square.square │ 16 │
# => ╰───┴─────────────────┴──────╯
```
# User-Facing Changes
No changes other than the new command.
# Tests + Formatting
Added tests for examples. (As we can't run them directly as tests yet.)
- 🟢 `toolkit test stdlib`
# After Submitting
- Update relevant parts of
https://www.nushell.sh/cookbook/jq_v_nushell.html
- `$env.config | recurse | where ($it.item | describe -d).type not-in
[list, record, table]` can partially cover the use case of `config
flatten`, should we do something?
---------
Co-authored-by: Bahex <17417311+Bahex@users.noreply.github.com>
|
2025-06-03 11:21:12 -04:00 |
|