In `nu`, there is no built-in function equivalent to `recurse`. However, we can reuse the solution from [Filtering nested items](#filtering-nested-items) to extract the values to manipulate:
```nu
'{"data": {"value": 42, "nested": {"value": 24}}}'
| from json
| cherry-pick { |x| $x.value? }
| compact
| each { |x| $x * 5 }
# => ╭───┬─────╮
# => │ 0 │ 210 │
# => │ 1 │ 120 │
# => ╰───┴─────╯
```
### Filtering and mapping over nested items
In `jq`, to filter and map over a tree we do:
```sh
echo '{"data": {"values": [1, 2, 3], "nested": {"values": [4, 5, 6]}}}' |
jq -r 'walk(if type == "number" then . * 2 else . end)'
```
In `nu`, there is no built-in function to achieve this. See the [Appendix: Custom commands](#appendix-custom-commands) for an implementation of the command `filter-map` shown in the example below.
```nu
'{"data": {"values": [1, 2, 3], "nested": {"values": [4, 5, 6]}}}'
| from json
| filter-map {|value| if ($value | describe) == "int" { $value * 2 } else { $value }}
# => ╭──────┬──────────────────────────────────────╮
# => │ │ ╭────────┬─────────────────────────╮ │
# => │ data │ │ │ ╭───┬───╮ │ │
# => │ │ │ values │ │ 0 │ 2 │ │ │
# => │ │ │ │ │ 1 │ 4 │ │ │
# => │ │ │ │ │ 2 │ 6 │ │ │
# => │ │ │ │ ╰───┴───╯ │ │
# => │ │ │ │ ╭────────┬────────────╮ │ │
# => │ │ │ nested │ │ │ ╭───┬────╮ │ │ │
# => │ │ │ │ │ values │ │ 0 │ 8 │ │ │ │
# => │ │ │ │ │ │ │ 1 │ 10 │ │ │ │
# => │ │ │ │ │ │ │ 2 │ 12 │ │ │ │
# => │ │ │ │ │ │ ╰───┴────╯ │ │ │
# => │ │ │ │ ╰────────┴────────────╯ │ │
# => │ │ ╰────────┴─────────────────────────╯ │
# => ╰──────┴──────────────────────────────────────╯
```
## Grouping and aggregating
### Grouping records by key
In `jq`, to group a list of records by key we do:
```sh
echo '[{"category": "A", "value": 10}, {"category": "B", "value": 20}, {"category": "A", "value": 5}]' |
jq -r 'group_by(.category)'
```
In `nu` we do:
```nu
'[{"category": "A", "value": 10}, {"category": "B", "value": 20}, {"category": "A", "value": 5}]'
| from json
| group-by --to-table category
# => ╭───┬───────┬──────────────────────────╮
# => │ # │ group │ items │
# => ├───┼───────┼──────────────────────────┤
# => │ 0 │ A │ ╭───┬──────────┬───────╮ │
# => │ │ │ │ # │ category │ value │ │
# => │ │ │ ├───┼──────────┼───────┤ │
# => │ │ │ │ 0 │ A │ 10 │ │
# => │ │ │ │ 1 │ A │ 5 │ │
# => │ │ │ ╰───┴──────────┴───────╯ │
# => │ 1 │ B │ ╭───┬──────────┬───────╮ │
# => │ │ │ │ # │ category │ value │ │
# => │ │ │ ├───┼──────────┼───────┤ │
# => │ │ │ │ 0 │ B │ 20 │ │
# => │ │ │ ╰───┴──────────┴───────╯ │
# => ╰───┴───────┴──────────────────────────╯
```
Note that `--to-table` was added to Nushell in [version 0.87.0](blog/2023-11-14-nushell_0_87_0.html). Before that you had to [`transpose`](/commands/docs/transpose) the record resulting from `group-by` which was substantially slower for large sets.
### Aggregating grouped values
In `jq`, to aggregate grouped values we do:
```sh
echo '[{"category": "A", "value": 10}, {"category": "B", "value": 20}, {"category": "A", "value": 5}]' |
jq -r 'group_by(.category) | map({category: .[0].category, sum: map(.value) | add})'
```
In `nu` we do:
```nu
'[{"category": "A", "value": 10}, {"category": "B", "value": 20}, {"category": "A", "value": 5}]'
| from json
| group-by --to-table category
| update items { |row| $row.items.value | math sum }
| rename category sum
```
### Filtering after aggregating
In `jq`, to filter after aggregating we do:
```sh
echo '[{"category": "A", "value": 10}, {"category": "B", "value": 20}, {"category": "A", "value": 5}]' |
jq -r 'group_by(.category) | map({category: .[0].category, sum: (map(.value) | add)}) | .[] | select(.sum > 17)'