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.
5. $names | each -n { |it| $"($it.index + 1) - ($it.item)" }
6. # 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].
4. let scores = [7 10 8 6 7]
5. 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
4. echo "total =" ($scores | math sum) # easier approach, same result
6. echo "product =" ($scores | reduce --fold 1 { |it, acc| $acc * $it }) # 96
8. 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
4. let colors = []
5. $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
4. # Is the length of any color name less than 3?
5. echo $colors | any? ($it | str length) < 3 # false
7. # Are any scores greater than 7?
8. echo $scores | any? $it > 7 # true
10. # Are any scores odd?
11. 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
4. # Is the length of all color names greater than or equal to 3?
5. echo $colors | all? ($it | str length) >= 3 # true
7. # Are all scores greater than 7?
8. echo $scores | all? $it > 7 # false
10. # Are all scores even?
11. 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]
3. 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]
3. # Show world clock for selected time zones
4. $zones | wrap 'Zone' | upsert Time {|it| (date now | date to-timezone $it.Zone | date format '%Y.%m.%d %H:%M')}
