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. > [1, 2, 3, 4] | insert 2 10

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

  1. > [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:

  1. let colors = [yellow green]
  2. let colors = ($colors | prepend red)
  3. let colors = ($colors | append purple)
  4. echo $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| echo $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:

  1. let names = [Mark Tami Amanda Jeremy]
  2. $names | each { |it| $"Hello, ($it)!" }
  3. # Outputs "Hello, Mark!" and three more similar lines.
  4. $names | each -n { |it| $"($it.index + 1) - ($it.item)" }
  5. # 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”.

  1. let colors = [red orange yellow green blue purple]
  2. echo $colors | where ($it | str ends-with 'e')

In this example, we keep only values higher than 7.

  1. # The block passed to where must evaluate to a boolean.
  2. # This outputs the list [orange blue purple].
  3. let scores = [7 10 8 6 7]
  4. echo $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:

  1. let scores = [3 8 4]
  2. echo "total =" ($scores | reduce { |it, acc| $acc + $it }) # 15
  3. echo "total =" ($scores | math sum) # easier approach, same result
  4. echo "product =" ($scores | reduce --fold 1 { |it, acc| $acc * $it }) # 96
  5. echo $scores | reduce -n { |it, acc| $acc + $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.

  1. let names = [Mark Tami Amanda Jeremy]
  2. $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.

  1. let names = [Mark Tami Amanda Jeremy]
  2. let index = 1
  3. $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 empty? command determines whether a string, list, or table is empty. It can be used with lists as follows:

  1. let colors = [red green blue]
  2. $colors | empty? # false
  3. let colors = []
  4. $colors | empty? # true

The in and not-in operators are used to test whether a value is in a list. For example:

  1. let colors = [red green blue]
  2. 'blue' in $colors # true
  3. 'yellow' in $colors # false
  4. 'gold' not-in $colors # true

The any? command determines if any item in a list matches a given condition. For example:

  1. # Do any color names end with "e"?
  2. echo $colors | any? ($it | str ends-with "e") # true
  3. # Is the length of any color name less than 3?
  4. echo $colors | any? ($it | str length) < 3 # false
  5. # Are any scores greater than 7?
  6. echo $scores | any? $it > 7 # true
  7. # Are any scores odd?
  8. echo $scores | any? $it mod 2 == 1 # true

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

  1. # Do all color names end with "e"?
  2. echo $colors | all? ($it | str ends-with "e") # false
  3. # Is the length of all color names greater than or equal to 3?
  4. echo $colors | all? ($it | str length) >= 3 # true
  5. # Are all scores greater than 7?
  6. echo $scores | all? $it > 7 # false
  7. # Are all scores even?
  8. echo $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. echo [1 [2 3] 4 [5 6]] | flatten # [1 2 3 4 5 6]
  2. echo [[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:

  1. let zones = [UTC CET Europe/Moscow Asia/Yekaterinburg]
  2. # Show world clock for selected time zones
  3. $zones | wrap 'Zone' | upsert Time {|it| (date now | date to-timezone $it.Zone | date format '%Y.%m.%d %H:%M')}