Home Explore Blog CI



nushell

5th chunk of `cookbook/jq_v_nushell.md`
31e545b8d1a1e807c4ab6870af381570c6710af9a1c9c6a00000000100001305
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)'
```

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 value
| where value > 17
# => ╭───┬──────────┬───────╮
# => │ # │ category │ value │
# => ├───┼──────────┼───────┤
# => │ 0 │ B        │    20 │
# => ╰───┴──────────┴───────╯
```

### Custom aggregations

In `jq`, to apply a custom aggregation we do:

```sh
echo '[{"value": 10}, {"value": 20}, {"value": 30}]' |
jq -r 'reduce .[] as $item (0; . + $item.value)'
```

In `nu` we do:

```nu
'[{"value": 10}, {"value": 20}, {"value": 30}]'
| from json
| reduce -f 0 { |item, acc| $acc + $item.value }
# => 60
```

## Other operations

### Calculating averages

In `jq`, to calculate an average we do:

```sh
echo '[{"score": 90}, {"score": 85}, {"score": 95}]' |
jq -r 'map(.score) | add / length'
```

In `nu` we do:

```nu
'[{"score": 90}, {"score": 85}, {"score": 95}]'
| from json
| get score
| math avg
# => 90
```

### Generating histogram bins

In `jq`, to calculate bins for a histogram we do:

```sh
echo '[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]' |
jq -r 'group_by(. / 5 | floor * 5) | map({ bin: .[0], count: length })'
```

In `nu` we do:

```nu
'[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]'
| from json
| group-by --to-table { $in // 5 * 5 }
| each { |row| {bin: $row.items.0, count: ($row.items | length)} }
# => ╭───┬─────┬───────╮
# => │ # │ bin │ count │
# => ├───┼─────┼───────┤
# => │ 0 │   1 │     4 │
# => │ 1 │   5 │     5 │
# => │ 2 │  10 │     5 │
# => │ 3 │  15 │     1 │
# => ╰───┴─────┴───────╯
```

Note that if what you are after is computing a histogram, you can benefit from the [`histogram`](/commands/docs/histogram) command.

## Appendix: Custom commands

This section provides the implementation of the custom commands used in this cookbook. Note that they are illustrative and in no way optimised for large inputs. If you are interested in that, [plugins](/book/plugins.html) will likely be the answer as they can be written in general purpose languages such as Rust or Python.

```nu
use toolbox.nu *
help commands | where command_type == "custom"
# => ╭──────┬─────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────╮
# => │    # │          name           │                                              usage                                              │
# => ├──────┼─────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────┤
# => │    0 │ cherry-pick             │ A command for cherry-picking values from a record key recursively                               │
# => │    1 │ filter-map              │ A command for walking through a complex data structure and transforming its values recursively  │

Title: Aggregating, Filtering, Custom Aggregations, and Other Operations: jq vs Nushell
Summary
This section compares how `jq` and Nushell handle various data operations, including aggregating grouped values, filtering after aggregation, and applying custom aggregations. It showcases equivalent `jq` and Nushell code snippets for each operation. Additionally, it demonstrates how to calculate averages and generate histogram bins in both tools. Finally, it references an appendix that contains custom commands implemented in Nushell.