Working with lists

Creating lists

A list is an ordered collection of values. You can create a list with square brackets, surrounded values separated by spaces and/or commas (for readability). For example, [foo bar baz] or [foo, bar, baz].

Updating lists

You can update and 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

We can also use update to replace the 2nd element with the value 10.

> [1, 2, 3, 4] | update 1 10

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)
$colors # [red yellow green purple]

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. |it| in { |it| print $it }) is normally the current list item, but the --numbered (-n) flag can change it to have index and item values if needed. For example:

let names = [Mark Tami Amanda Jeremy]
$names | each { |it| $"Hello, ($it)!" }
# Outputs "Hello, Mark!" and three more similar lines.

$names | each -n { |it| $"($it.index + 1) - ($it.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 it) and an accumulator (conventionally named acc). To specify an initial value for the accumulator, use the --fold (-f) flag. To change it to have index and item values, add the --numbered (-n) flag. For example:

let scores = [3 8 4]
$"total = ($scores | reduce { |it, acc| $acc + $it })" # total = 15

$"total = ($scores | math sum)" # easier approach, same result

$"product = ($scores | reduce --fold 1 { |it, acc| $acc * $it })" # total = 96

$scores | reduce -n { |it, acc| $acc.item + $it.index * $it.item } # 3 + 1*8 + 2*4 = 19

Accessing the list

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:

# Do any color names end with "e"?
$colors | any ($it | str ends-with "e") # true

# Is the length of any color name less than 3?
$colors | any ($it | str length) < 3 # false

# Are any scores greater than 7?
$scores | any $it > 7 # true

# Are any scores odd?
$scores | any $it mod 2 == 1 # true

The all command determines if every item in a list matches a given condition. For example:

# Do all color names end with "e"?
$colors | all ($it | str ends-with "e") # false

# Is the length of all color names greater than or equal to 3?
$colors | all ($it | str length) >= 3 # true

# Are all scores greater than 7?
$scores | all $it > 7 # false

# Are all scores even?
$scores | all $it 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 {|it| (date now | date to-timezone $it.Zone | date format '%Y.%m.%d %H:%M')}
Contributors: Reilly Wood, Anton Patrushev, JT, JT, Justin Ma, Zephaniah Ong, Darren Schroeder, Hafi the Cat, JT, Leon, R. Mark Volkmann, Reilly Wood, Stefan Holderbach, Zhora Trush, chtenb, morzel85