# Built-in Functions for Manipulating Arrays

[Arrays](https://icheka-ozuru.gitbook.io/sonarlang/syntax-basics/data-structures/arrays) introduced two built-in functions: **push()** and **pop()**. This section will explore a few more.

### len()

**len()** is used to get the number of elements in an array (i.e the **len**gth of the array).

```javascript
>> len([1,2,3])
// outputs 3
```

### slice()

**slice()** returns a section of the array (i.e slices it). The first argument to **slice** must be an array or string. The second and third arguments to **slice()** are optional and are named *start* and *end*.

*start:* specifies where to start slicing from (i.e the index of the first element in the array or string that will be returned.)

*end:* specifies where to stop slicing at (i.e the index of the element one level above the last element to return).&#x20;

```javascript
>> slice([1,2,3,4], 1, 3)
// outputs [2, 3] because start (1) is 2 and end (3) is 4 but 4 won't be returned

>> slice([2,4,6,8,10,12,14], 2, 6)
// outputs [6, 8, 10, 12]

// slice() also works on strings
>> slice("Hello World!", 4, 9)
// outputs "o Wor"
```

**slice()** can also take a fourth, optional, argument. This argument is called *step* and it is used to specify a "step" or "skip" value for the **slice** operation. The step value allows the **slice()** function to skip certain elements in the original array depending on whether the modulus of the index of the element and the step value is equal to 0.&#x20;

If this sounds really complex, the following example will explain:

```javascript
let arr = [1,2,3,4,5,6,7,8]
print(slice(arr, 0, 8))
// [1, 2, 3, 4, 5, 6, 7, 8]

print(slice(arr, 0, 8, 2))
// [1, 3, 5, 7]
// slice picks the first element (at the 'start' index)
// then it picks every 2nd element (the value of the step argument) until it gets to the end-index value

print(slice(arr, 0, 8, 3))
// [1, 4, 7]
// slice picks the first element (at the 'start' index)
// then it picks every 3rd element (the value of the step argument) until it gets to the end-index value
```

### contains()

**contains()** checks whether an array or string contains a certain element (which can be a string, number, boolean, map, function or another array).

```javascript
>> let arr = [1, 2, 3, "Hey", [10, 11, 12], true]

>> contains(arr, 1]
// true

>> contains(arr, "Hey")
// true

>> contains(arr, "hey")
// false (hey is not the same string as Hey)

>> contains(arr, [10, 11, 12])
// true

>> contains(arr, true)
// true
```

```javascript
>> let str = "Hello World!"

>> contains(str, "Hey")
// false

>> contains(str, "ello")
// true
```

### index()

**index()** requires two arguments: an array or string, and a **value** (number, string, etc). It returns the index of the first occurrence of **value** in the array or string.

```javascript
>> let arr = [1, 2, 3, 4]
>> index(arr, 2)
// outputs 1

>> let str = "Hello"
>> index(str, "l")
// outputs 2
```

If **value** wasn't found at all, **index()** returns -1.

```javascript
>> let arr = [1, 2, 3, 4]
>> index(arr, "H")
// outputs -1
```

### sort()

**sort()** sorts an array's elements in ascending order and returns a new array containing the sorted elements. It does not change the order of original array.

```javascript
>> let arr = [1, 2, 3, 0]
>> sort(arr)
// outputs [0, 1, 2, 3]
```

String elements can be sorted too.

```javascript
>> let arr2 = [1, 2, 3, 0, "A", "a", "B", "b"]
>> sort(arr2)
// outputs [0, 1, 2, 3, A, B, a, b]
```

### Rules of Sorting Elements

> Feel free to skip this section if you have never studied sorting algorithms.

The sort algorithm **Sonar** uses is based on Go's *pdqsort (Pattern-defeating quicksort)* algorithm. Without launching into a deep conversation into sorting algorithms and their trade-offs, we can state here that the decision to base **Sonar**'s **sort()** on Go's *pdqsort* was made for the following reasons:

1. *pdqsort* is a very fast algorithm
2. No other reason

Given that **Sonar**'s **sort()** is based on *pdqsort*, it is a fast, albeit non-"stable" sort implementation. Please, note that "non-stable", as used here, does not mean "un-reliable". See this [Wikipedia exposé on stable and non-stable sorting algorithms](https://en.wikipedia.org/wiki/Category:Stable_sorts).)

**sort()** sorts elements according to their position in the [ASCII table](https://www.ascii-code.com/).

### reverse()

**reverse()** reverses the position of an array's elements, and returns a new array with the new order. The original array is left unchanged.

```javascript
>> let arr = [1, 2, 3]
>> reverse(arr)
// [3, 2, 1]
```
