In programming, loops that operate on consecutive elements of a list are common, so we offer various ways to apply functions to each of the elements of a list, along with various ways to treat the returned values.
The most basic operation is provided by
scan, which applies a function consecutively to each element of a list, discarding the values returned.
i1 : scan({a,b,c}, print)
a
b
c
|
The keyword
break can be used to terminate the scan prematurely, and optionally to specify a return value for the expression. Here we use it to locate the first even number in a list.
i2 : scan({3,5,7,11,44,55,77}, i -> if even i then break i)
o2 = 44
|
The function
apply is similar to
scan but will produce a list containing the values returned.
i3 : apply({1,2,3,4}, i -> i^2)
o3 = {1, 4, 9, 16}
o3 : List
|
This operation is so common that we offer two shorthand notations for it, one with the function on the right and one with the function on the left.
i4 : {1,2,3,4} / (i -> i^2)
o4 = {1, 4, 9, 16}
o4 : List
|
i5 : (i -> i^2) \ {1,2,3,4}
o5 = {1, 4, 9, 16}
o5 : List
|
The associativity of these operators during parsing is set up so the following code works as one would wish.
i6 : {1,2,3,4} / (i -> i^2) / (j -> 1000*j)
o6 = {1000, 4000, 9000, 16000}
o6 : List
|
i7 : (j -> 1000*j) \ (i -> i^2) \ {1,2,3,4}
o7 = {1000, 4000, 9000, 16000}
o7 : List
|
i8 : (j -> 1000*j) @@ (i -> i^2) \ {1,2,3,4}
o8 = {1000, 4000, 9000, 16000}
o8 : List
|
The function
apply can also be used with two lists of the same length, in which case it will apply the function consecutively to corresponding elements of the two lists.
i9 : apply({1,2,3}, {7,8,9}, (i,j) -> 1000*i+j)
o9 = {1007, 2008, 3009}
o9 : List
|
The function
table can be used to create a table (doubly nested list) from two lists and a function of two arguments. It applies the function consecutively to each element from the first list paired with each element from the second list, so the total number of evaluations of the function is the product of the lengths of the two lists.
i10 : table({1,2,3},{7,8},(i,j) -> 1000*i+j)
o10 = {{1007, 1008}, {2007, 2008}, {3007, 3008}}
o10 : List
|
The function
applyTable can be used to apply a function to each element of table.
i11 : applyTable( {{1,2,3},{4,5}}, i -> i^2)
o11 = {{1, 4, 9}, {16, 25}}
o11 : List
|
We may use
select to select those elements from a list that satisfy some condition. In the next example, we use the function
even to select the even numbers from a list.
i12 : select({1,2,3,4,5,6,7,8,9,10}, even)
o12 = {2, 4, 6, 8, 10}
o12 : List
|
An optional first argument to
select allows us to specify the maximum number of elements selected.
i13 : select(2,{1,2,3,4,5,6,7,8,9,10}, even)
o13 = {2, 4}
o13 : List
|
We may use
any to tell whether there is at least one element of a list satisfying a condition, and
all to tell whether all elements satisfy it.
i14 : any({1,2,3,4,5,6,7,8,9,10}, even)
o14 = true
|
i15 : all({1,2,3,4,5,6,7,8,9,10}, even)
o15 = false
|
We can use
position to tell us the position of the first element in a list satisfying a condition.
i16 : position({1,3,5,7,8,9,11,13,15,16},even)
o16 = 4
|
The functions
fold and
accumulate provide various ways to apply a function of two arguments to the elements of a list. One of the arguments is the next element from the list, and the other argument is the value returned by the previous application of the function. As an example, suppose we want to convert the list
{7,3,5,4,2} of digits into the corresponding number
73542. The formula
(((7*10+3)*10+5)*10+4)+2 is a fast way to do it that doesn't involve computing high powers of 10 separately. We can do this with
fold and the following code.
i17 : fold((i,j) -> i*10+j, {7,3,5,4,2})
o17 = 73542
|
It is possible to give an additional argument to
fold so that lists of length 0 can be handled correctly.