## Elementary List Operations

### Creating and Accessing Lists

#### Creating an integer sequence: `‹int1›..‹int2›`

**Description:**
The expression `‹int1›..‹int2›`

creates a list of consecutive integers starting with `‹int1›`

and ending with `‹int2›`

.
If `‹int1›`

is larger than `‹int2›`

, then the empty list is returned.

4..9

[4, 5, 6, 7, 8, 9]

-2..2

[-2, -1, 0, 1, 2]

4..1

[]

#### The length of a list: `length(‹list›)`

**Description:**
This operator returns an integer that is equal to the number of elements in the `‹list›`

.

length([2 ,5 ,7 ,3])

4

length([2 ,[5, 4, 5] ,7 ,3]_2)

3

length(1..1000)

1000

Combining the `length`

and the `repeat`

operator allows one to list all elements of a list easily.

list = [2,3,5,7]; repeat(length(list), println(list_#); )

2 3 5 7

One word of caution here: CindyScript is designed in such a way that it is seldom useful to traverse all the elements of a list using the `repeat`

operator.
There are more elegant ways.

#### Testing for containment: `contains(‹list›,‹expr›)`

**Description:**
This operator returns either `true`

or `false`

depending on whether `‹list›`

contains the element `‹expr›`

.

contains([1,3,4,5],4)

true

contains([1,3,4,5],7)

false

contains([1,3,4,5],2*2)

true

CindyScript >=3.0

4 ∈ [1,3,4,5]

true

7 ∈ [1,3,4,5]

false

4 ∉ [1,3,4,5]

false

7 ∉ [1,3,4,5]

true

### List Manipulation

#### Concatenation of lists: `‹list1› ++ ‹list2›`

, `‹list1› ∪ ‹list2›`

or `concat(‹list1›,‹list2›)`

**Description:**
This operator creates a list by concatenation of two other lists.

concat(["a", "b"], ["c", "d"])

["a", "b", "c", "d"]

Thanks to auto-coercion, numbers and boolean values will get converted to singleton lists.

concat(2, true)

[2, true]

Strings and `___`

auto-coerce to the empty list.

concat("foo", [2])

[2]

concat([1], (;))

[1]

#### Removing elements from lists: `‹list1› -- ‹list2›`

, `‹list1› ∖ ‹list2›`

or `remove(‹list1›,‹list2›)`

**Description:**
This operator creates a list by removing all elements that occur in `‹list2›`

from `‹list1›`

.
Note that `∖`

is not a plain backslash, but the Unicode symbol ‘set minus’.

remove([1,3,4,5,1,5,6], [1,3,7])

[4, 5, 5, 6]

[1,3,4,5,1,5,6]--[1,3,7]

[4, 5, 5, 6]

#### Intersection of lists: `‹list1› ~~ ‹list2›`

, `‹list1› ∩ ‹list2›`

or `common(‹list1›,‹list2›)`

**Description:**
This operator creates a list collecting all elements that are in both `‹list1›`

and `‹list1›`

.
In the returned list the elements are sorted and each element occurs at most once.

common([1,3,4,5,1,5,6], [1,3,7])

[1, 3]

[1,3,4,5,1,5,6]~~[1,3,7]

[1, 3]

#### Appending an element: `‹list› :> ‹expr›`

or `append(‹list›,‹expr›)`

**Description:**
This operator returns a list that is created by appending `‹expr›`

to the list `‹list›`

as its last element.

append(["a", "b", "c"], "d")

["a", "b", "c", "d"]

["a", "b", "c"]:>"d"

["a", "b", "c", "d"]

#### Prepending an element: `‹expr› <: ‹list›`

or `prepend(‹expr›,‹list›)`

**Description:**
This operator returns a list that is created by prepending `‹expr›`

to the list `‹list›`

as its first element.

prepend("d",["a", "b", "c"])

["d", "a", "b", "c"]

"d"<:["a", "b", "c"]

["d", "a", "b", "c"]

### Traversing Lists

#### The forall loop: `forall(‹list›,‹expr›)`

**Description:**
This operator is useful for applying an operation to all elements of a list.
It takes a `‹list›`

as first argument.
It produces a loop in which `‹expr›`

is evaluated for each entry of the list.
For each run, the run variable `#`

takes the value of the corresponding list entry.

**Example:**

a=["this","is","a","list"]; forall(a,println(#))

This code fragment produces the output

this is a list

#### The forall loop: `forall(‹list›,‹var›,‹expr›)`

**Description:**
Similar to `forall(‹list›,‹expr›)`

, but the run variable is now named `‹var›`

.
The variable is local to the expression.

v=994; forall([1,2,3],v,println(v))

1 2 3

v

994

#### Applying an expression: `apply(‹list›,‹expr›)`

**Description:**
This operator generates a new list by applying the operation `‹expr›`

to all elements of a list and collecting the results.
As usual, `#`

is the run variable, which successively takes the value of each element in the list.

apply([1, 2, 3, 4, 5],#^2)

[1, 4, 9, 16, 25]

apply([1, 2, 3, 4, 5],#+5)

[6, 7, 8, 9, 10]

apply(1..5, [#,#^2])

[[1, 1], [2, 4], [3, 9], [4, 16], [5, 25]]

#### Applying an expression: `apply(‹list›,‹var›,‹expr›)`

**Description:**
Similar to `apply(‹list›,‹expr›)`

, but the run variable is now named `‹var›`

.
The variable is local to the expression.

v=995; apply([1, 2, 3, 4, 5], v, v^2)

[1, 4, 9, 16, 25]

v

995

#### Selecting elements of a list: `select(‹list›,‹boolexpr›)`

**Description:**
This operator selects all elements of a list for which a certain condition is satisfied.
The condition is supposed to be encoded by `‹boolexpr›`

.
This expression is assumed to return a `‹bool›`

value.
As usual, `#`

is the run variable, which successively take the value of all elements in the list.

select(1..10, isodd(#))

[1, 3, 5, 7, 9]

select(0..10, #+# == #^2)

[0, 2]

A high-level application of the `select`

operator is given by the following example:

divisors(x):=select(1..x,mod(x,#)==0); primes(n):=select(1..n,length(divisors(#))==2); println(primes(20))

It produces the output

[2, 3, 5, 7, 11, 13, 17, 19]

In this example, first a function `divisors(x)`

is defined by selecting those numbers that divide `x`

without any remainder.
Then a function `primes(n)`

is defined that selects all numbers between `1`

and `n`

that have exactly two divisors.
These numbers are the primes.

#### Selecting elements of a list: `select(‹list›,‹var›,‹boolexpr›)`

**Description:**
Similar to `select(‹list›,‹boolexpr›)`

, but the run variable is now named ‹var›.
The variable is local to the expression.

v = 996; select(0..10, v, v+v == v^2)

[0, 2]

v

996