[next][previous][up][top][index]
search for:

mapping over lists -- apply a function to each element of a list

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.


[next][previous][up][top][index]
search for: