# List Slice

rascal-0.33.7

#### Synopsis​

Retrieve a slice of a list.

#### Syntax​

• `Exp₁ [ Exp₂ .. Exp₄]`
• `Exp₁ [ Exp₂ , Exp₃ .. Exp₄]`

where Exp₂ and Exp₄ are optional.

#### Types​

//

`Exp₁``Exp₂``Exp₃``Exp₄``Exp₁ [ Exp₂ .. Exp₄ ]` or `Exp₁ [ Exp₂ , Exp₃ .. Exp₄]`
`list[T₁]``int``int``int``list[T₁]`

#### Description​

List slicing uses the integer values of Exp₂ and Exp₄ to determine the `begin` (inclusive) and `end` (exclusive) of a slice from the list value L of Exp₁. Negative indices count from the end of the list backwards. Using the second form, an extra index Exp₃ is given that determines the index of the second element in the slice and establishes the `step` between successive elements in the slice. The default `step` is 1. If `end` is smaller than `begin`, the slice is constructed backwards.

Let `Len` be the length of L and let N₂, N₃ and N₄ be the respective values of the expressions Exp₂, Exp₂ and Exp₂ when they are present.

The slice parameters `begin`, `end`, and `step` are determined as follows:

• Exp₂: If Exp₂ is absent, then `begin = 0`. Otherwise, if N₂ >= 0 then `begin = N₂` else `begin = N₂ + Len`.
• Exp₄: If Exp₄ is absent, then `end = Len`. Otherwise, if N₄ >= 0, then `end = N₄` else `end = N₄ + Len`.
• Exp₃: If Exp₃ is absent, then if `begin < end` then `step = 1` else `step = -1`. Otherwise, if `begin < end`, then `step = N₃ - begin` else `step = begin - N₃`.

Now, the constraints `0 <= begin < Len` and `0 < end < Len` should hold, otherwise the exception `IndexOutOfBounds` is thrown.

The slice consists of the elements `L[begin]`, `L[begin+step]`, `L[end - step]`. When `begin >= end`, the elements are listed in reverse order.

#### Examples​

Consider the list `L = [0, 10, 20, 30, 40, 50, 60, 70, 80];` as running example.

Here is a view on L that will help to correlate positive and negative indices:

`i`012345678
`L[i]`01020304050607080
`-i`-9-8-7-6-5-4-3-2-1

Some common use cases (with `begin` <= `end`):

SliceMeans:
`L[begin..end]`elements with indices `begin` through `end-1`
`L[begin..]`elements with indices `begin` through the rest of the list
`L[..end]`elements with indices from the beginning through `end-1`
`L[..]`the whole list
`L[-1]`last element of the list
`L[-2..]`the last two elements of the list
`L[..-2]`all elements except the last two.

Let's put this into practice now.

``rascal>L = [0, 10, 20, 30, 40, 50, 60, 70, 80];list[int]: [0,10,20,30,40,50,60,70,80]``

Slices with begin < end

``rascal>L[1..3];list[int]: [10,20]rascal>L[1..];       // empty end => end of listlist[int]: [10,20,30,40,50,60,70,80]rascal>L[..3];       // empty begin => first element of listlist[int]: [0,10,20]rascal>L[..];        // both empty => whole listlist[int]: [0,10,20,30,40,50,60,70,80]``

Slices with begin >= end

``rascal>L[3..1];      // slice contains elements with indices 3 and 2 (in that order)list[int]: [30,20]rascal>L[3..3];      // empty slice when begin == endlist[int]: []``

Slices with negative begin or end:

``rascal>L[2..-2];     // equivalent to L[2..7]list[int]: [20,30,40,50,60]rascal>L[2..7];list[int]: [20,30,40,50,60]rascal>L[-4..-2];    // equivalent to L[5..7]list[int]: [50,60]rascal>L[5..7];list[int]: [50,60]``

Slices with an explicit second index:

``rascal>L[1,3..6];list[int]: [10,30,50]rascal>L[5,3..];list[int]: [50,30,10]``

Slices not do go "out of bounds". Instead they just stop at the end or beginning:

``rascal>L[..10];list[int]: [0,10,20,30,40,50,60,70,80]rascal>L[..-11];list[int]: ``