Working with Lists
Tips
Lists are equivalent to the individual columns of tables. You can think of a list as essentially being a "one-column table" (with no column name). Thus, any command which operates on a column also operates on a list. For instance, where
can be used with lists:
> [bell book candle] | where ($it =~ 'b')
╭───┬──────╮
│ 0 │ bell │
│ 1 │ book │
╰───┴──────╯
Creating lists
A list is an ordered collection of values. A list is created using square brackets surrounding values separated by spaces, linebreaks, and/or commas. For example, [foo bar baz]
or [foo, bar, baz]
.
Tips
Nushell lists are similar to JSON arrays. The same [ "Item1", "Item2", "Item3" ]
that represents a JSON array can also be used to create a Nushell list.
Updating lists
We can insert
values into lists as they flow through the pipeline, for example let's insert the value 10
into the middle of a list:
> [1, 2, 3, 4] | insert 2 10
# [1, 2, 10, 3, 4]
We can also use update
to replace the 2nd element with the value 10
.
> [1, 2, 3, 4] | update 1 10
# [1, 10, 3, 4]
Removing or Adding Items from List
In addition to insert
and update
, we also have prepend
and append
. These let you insert to the beginning of a list or at the end of the list, respectively.
For example:
let colors = [yellow green]
let colors = ($colors | prepend red)
let colors = ($colors | append purple)
let colors = ($colors ++ "blue")
let colors = ("black" ++ $colors)
$colors # [black red yellow green purple blue]
In case you want to remove items from list, there are many ways. skip
allows you skip first rows from input, while drop
allows you to skip specific numbered rows from end of list.
let colors = [red yellow green purple]
let colors = ($colors | skip 1)
let colors = ($colors | drop 2)
$colors # [yellow]
We also have last
and first
which allow you to take
from the end or beginning of the list, respectively.
let colors = [red yellow green purple black magenta]
let colors = ($colors | last 3)
$colors # [purple black magenta]
And from the beginning of a list,
let colors = [yellow green purple]
let colors = ($colors | first 2)
$colors # [yellow green]
Using the Spread Operator
To append one or more lists together, optionally with values interspersed in between, you can also use the spread operator (...
):
> let x = [1 2]
> [
...$x
3
...(4..7 | take 2)
]
╭───┬───╮
│ 0 │ 1 │
│ 1 │ 2 │
│ 2 │ 3 │
│ 3 │ 4 │
│ 4 │ 5 │
╰───┴───╯
Iterating over Lists
To iterate over the items in a list, use the each
command with a block of Nu code that specifies what to do to each item. The block parameter (e.g. |elt|
in { |elt| print $elt }
) is the current list item, but the enumerate
filter can be used to provide index
and item
values if needed. For example:
let names = [Mark Tami Amanda Jeremy]
$names | each { |elt| $"Hello, ($elt)!" }
# Outputs "Hello, Mark!" and three more similar lines.
$names | enumerate | each { |elt| $"($elt.index + 1) - ($elt.item)" }
# Outputs "1 - Mark", "2 - Tami", etc.
The where
command can be used to create a subset of a list, effectively filtering the list based on a condition.
The following example gets all the colors whose names end in "e".
let colors = [red orange yellow green blue purple]
$colors | where ($it | str ends-with 'e')
# The block passed to `where` must evaluate to a boolean.
# This outputs the list [orange blue purple].
In this example, we keep only values higher than 7
.
let scores = [7 10 8 6 7]
$scores | where $it > 7 # [10 8]
The reduce
command computes a single value from a list. It uses a block which takes 2 parameters: the current item (conventionally named elt
) and an accumulator (conventionally named acc
). To specify an initial value for the accumulator, use the --fold
(-f
) flag. To change elt
to have index
and item
values, use the enumerate
filter. For example:
let scores = [3 8 4]
$"total = ($scores | reduce { |elt, acc| $acc + $elt })" # total = 15
$"total = ($scores | math sum)" # easier approach, same result
$"product = ($scores | reduce --fold 1 { |elt, acc| $acc * $elt })" # product = 96
$scores | enumerate | reduce --fold 0 { |elt, acc| $acc + $elt.index * $elt.item } # 0*3 + 1*8 + 2*4 = 16
Accessing the List
Note
The following is a basic overview. For a more in-depth discussion of this topic, see the chapter, Navigating and Accessing Structured Data.
To access a list item at a given index, use the $name.index
form where $name
is a variable that holds a list.
For example, the second element in the list below can be accessed with $names.1
.
let names = [Mark Tami Amanda Jeremy]
$names.1 # gives Tami
If the index is in some variable $index
we can use the get
command to extract the item from the list.
let names = [Mark Tami Amanda Jeremy]
let index = 1
$names | get $index # gives Tami
The length
command returns the number of items in a list. For example, [red green blue] | length
outputs 3
.
The is-empty
command determines whether a string, list, or table is empty. It can be used with lists as follows:
let colors = [red green blue]
$colors | is-empty # false
let colors = []
$colors | is-empty # true
The in
and not-in
operators are used to test whether a value is in a list. For example:
let colors = [red green blue]
'blue' in $colors # true
'yellow' in $colors # false
'gold' not-in $colors # true
The any
command determines if any item in a list matches a given condition. For example:
let colors = [red green blue]
# Do any color names end with "e"?
$colors | any {|elt| $elt | str ends-with "e" } # true
# Is the length of any color name less than 3?
$colors | any {|elt| ($elt | str length) < 3 } # false
let scores = [3 8 4]
# Are any scores greater than 7?
$scores | any {|elt| $elt > 7 } # true
# Are any scores odd?
$scores | any {|elt| $elt mod 2 == 1 } # true
The all
command determines if every item in a list matches a given condition. For example:
let colors = [red green blue]
# Do all color names end with "e"?
$colors | all {|elt| $elt | str ends-with "e" } # false
# Is the length of all color names greater than or equal to 3?
$colors | all {|elt| ($elt | str length) >= 3 } # true
let scores = [3 8 4]
# Are all scores greater than 7?
$scores | all {|elt| $elt > 7 } # false
# Are all scores even?
$scores | all {|elt| $elt mod 2 == 0 } # false
Converting the List
The flatten
command creates a new list from an existing list by adding items in nested lists to the top-level list. This can be called multiple times to flatten lists nested at any depth. For example:
[1 [2 3] 4 [5 6]] | flatten # [1 2 3 4 5 6]
[[1 2] [3 [4 5 [6 7 8]]]] | flatten | flatten | flatten # [1 2 3 4 5 6 7 8]
The wrap
command converts a list to a table. Each list value will be converted to a separate row with a single column:
let zones = [UTC CET Europe/Moscow Asia/Yekaterinburg]
# Show world clock for selected time zones
$zones | wrap 'Zone' | upsert Time {|row| (date now | date to-timezone $row.Zone | format date '%Y.%m.%d %H:%M')}