Algorithms#

Nushell’s table operations replace the bulk of what bash operators reach for sort, uniq, awk, and jq to do. sort-by, group-by, uniq, where, reduce, and join cover the patterns operators run into most. For genuine algorithm work, Nu has lists, recursion, and closures the same as any modern scripting language.

Filter#

where is the workhorse. The predicate can reference $it (implicit current value) or take a closure with a named parameter.

ls | where size > 1MB
ls | where modified > (date now) - 1day
open users.json | where age > 30 and region == "us-east"

Sorting#

sort (for lists) and sort-by (for tables) cover the standard cases. Multi-key, descending, natural, case- insensitive.

[10 2 33 4 5] | sort                            # [2 4 5 10 33]
[10 2 33 4 5] | sort --reverse                  # [33 10 5 4 2]
["B" "a" "C"] | sort --insensitive               # [a B C]

$rows | sort-by size
$rows | sort-by size --reverse
$rows | sort-by region name                     # multi-key
ls | sort-by --natural name                     # 2 < 10 < 100

Dedup#

uniq works on lists; uniq-by works on tables (dedupe by column). uniq --count returns the count per distinct value.

[a b a c b a] | uniq                            # [a b c]
[a b a c b a] | uniq --count                    # table with value+count
$rows | uniq-by region                          # one row per region

Grouping#

group-by produces a record whose keys are the group values and whose values are tables of matching rows. transpose then flattens that back into “name + group” rows the way Group-Object does.

$users | group-by region

$users
    | group-by region
    | transpose region members
    | upsert count { |row| $row.members | length }
    | sort-by count --reverse

Joining#

Tables can join on a common column. The standard relational operation, in shell.

let users = [[id name]; [1 alice] [2 bob] [3 carol]]
let roles = [[user_id role]; [1 admin] [3 viewer]]

$users | join $roles id user_id --left

Aggregate#

math is the namespace. math sum, math avg, math min, math max, math median, math stddev.

[10 20 30 40] | math sum                        # 100
[10 20 30 40] | math avg                        # 25
ls | get size | math sum

For a table grouped by column, combine group-by and each.

$users
    | group-by region
    | transpose region rows
    | each { |g| {region: $g.region, total_age: ($g.rows | get age | math sum)} }

Reduce#

reduce folds a list into a single value with a closure.

[1 2 3 4 5] | reduce { |it, acc| $acc + $it }   # 15
[1 2 3 4 5] | reduce --fold 1 { |it, acc| $acc * $it }   # factorial 120

Recursion#

def factorial [n: int] {
    if $n <= 1 { 1 } else { $n * (factorial ($n - 1)) }
}

factorial 5                                     # 120

For numeric work, the reduce form is faster (no recursion overhead). For tree traversal where recursion is natural, Nu holds up like any modern language; it does not have tail-call optimization, so very deep recursions hit a stack limit.

References#