mapping over lists

In programming, loops which 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

By contrast, apply will produced a list containing the values returned.

i2 : apply({1,2,3,4}, i -> i^2)

o2 = {1, 4, 9, 16}

o2 : 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.

i3 : {1,2,3,4} / (i -> i^2)

o3 = {1, 4, 9, 16}

o3 : List
i4 : (i -> i^2) \ {1,2,3,4}

o4 = {1, 4, 9, 16}

o4 : List

The associativity of these operators during parsing is set up so the following code works as one would wish.

i5 : {1,2,3,4} / (i -> i^2) / (j -> 1000*j)

o5 = {1000, 4000, 9000, 16000}

o5 : List
i6 : (j -> 1000*j) \ (i -> i^2) \ {1,2,3,4}

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

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.

i8 : apply({1,2,3}, {7,8,9}, (i,j) -> 1000*i+j)

o8 = {1007, 2008, 3009}

o8 : 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 an element from the first list and an element from the second list.

i9 : table({1,2,3},{7,8},(i,j) -> 1000*i+j)

o9 = {{1007, 1008}, {2007, 2008}, {3007, 3008}}

o9 : List

The function applyTable can be used to apply a function to each element of a doubly nested list (table). Occasionally matrices are represented as a table, so this is a useful facility.

i10 : applyTable( {{1,2,3},{4,5}}, i -> i^2)

o10 = {{1, 4, 9}, {16, 25}}

o10 : 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.

i11 : select({1,2,3,4,5,6,7,8,9,10}, even)

o11 = {2, 4, 6, 8, 10}

o11 : List

An optional first argument to select allows us to specify the maximum number of elements selected.

i12 : select(2,{1,2,3,4,5,6,7,8,9,10}, even)

o12 = {2, 4}

o12 : 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.

i13 : any({1,2,3,4,5,6,7,8,9,10}, even)

o13 = true
i14 : all({1,2,3,4,5,6,7,8,9,10}, even)

o14 = false

We can use position to tell us the position of the first element in a list satisfying a condition.

i15 : position({1,3,5,7,8,9,11,13,15,16},even)

o15 = 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.

i16 : fold((i,j) -> i*10+j, {7,3,5,4,2})

o16 = 73542

It is possible to give an additional argument to fold so that lists of length 0 can be handled correctly.
topindexpreviousupnext