# JS - Arrays

## Declaration and Initialization

`const myArr = new Array(1, 2, 3, 4, 5, true,"gambit")`

or

`const myArr = [1, 2, 3, 4, 5, true,"gambit"]`

**Pointer:**

*   Array is an object that has a collection of multiple items with any data type.
    
*   the 'new' keyword can be skipped in js while declaring arrays
    
*   Arrays in javascript are resizable. You can add or remove elements.
    
*   To access individual array element use index starting from 0 ending with array length-1, `myArr[5]` -> true
    
*   If you try to access an item outside the length of array it will return undefined.
    
*   Array copy operations result in reference copies, this means when copying an array you get a reference to the original array not a copy. So any changes in the copy also affect the original.
    

```javascript
const myArr = [1,2,3,4,5,true,"gambit"]
let a = myArr
a[0] = 'a'
console.log(myArr); // [ 'a', 2, 3, 4, 5, true, 'gambit' ]
```

## Making empty arrays

```javascript
const threeEmptySeats = Array(3)
console.log(threeEmptySeats.length)
// 3
console.log(threeEmptySeats)
// [ <3 empty items> ]
```

Note if you declare array like, `const threeEmptySeats = [3]`, it means array with only one element with the item 3.

Since this makes making array with 1 element only a bit confusing better to use \[\] or `Array.of()` discussed later

```javascript
const arr = Array(3).fill(0)

console.log(arr)
// [ 0, 0, 0 ]
```

### .fill(value, start, end)

If you wanna make an array with elements having 0 in all the indexes.

*   **value:** The value to fill the array with.
    
*   **start** (optional): The index to start filling (default is `0`).
    
*   **end** (optional): The index to stop filling (exclusive, default is `array.length`).
    

## push, pop, unshift, shift

```javascript
const myArr = [1,2,3,4,5]

myArr.push(6)
myArr.push(7)
console.log(myArr) 
// [ 1, 2, 3, 4, 5, 6, 7 ]

myArr.pop()
console.log(myArr)
// [ 1, 2, 3, 4, 5, 6 ]

console.log(myArr.length)
// 6

myArr.unshift(0)
console.log(myArr)
// [ 0, 1, 2, 3, 4, 5, 6 ]

myArr.shift()
myArr.shift()
console.log(myArr)
// [ 2, 3, 4, 5, 6 ]
```

**Pointers**

*   .push(value) : simply adds the value at the end of the array and increases the length of the array.
    
*   .pop() : removes the last element of the array and reduces the array length.
    
*   .length -> returns the length of the array or the number of items it has.
    
*   .unshift(value) -> adds item at the start of the array
    
*   .shift() -> removes the first item of the array.
    
*   Both shift and unshift are more time consuming than push and pop since they need to shift all the elements after it causing O(N) time complexity, where as pop and push have O(1) Time complexity.
    

## Truncating array using .length

```javascript
const letters = ['a','b','c','d','e']

letters.length = 3
console.log(letters) // [ 'a', 'b', 'c' ]

// data is lost even if you bring it back to old length
letters.length = 5
console.log(letters) 
// [ 'a', 'b', 'c', <2 empty items> ]
```

## includes, indexOf

```javascript
const myArr = [1,2,3,'car',4,5]

console.log(myArr.includes(3))      // true
console.log(myArr.includes(6))      // false   

console.log(myArr.indexOf('car'))   // 3
console.log(myArr.indexOf(8))       // -1
```

**Pointers**

*   .includes(value) -> returns true or false if the value is found within the array
    
*   .indexOf(value) -> returns the index where are the value is found first within the array or -1 in case it isn't found.
    

## join

```javascript
const myArr1 = [1,2,3]

console.log(myArr1.join())          // 1,2,3
console.log(myArr1.join("-"))       // 1-2-3
console.log(typeof myArr1.join())   // string
```

.join() method is used to convert an array into string separated by commas, if we don't wanna use comma we can add a custom separator in the argument.

undefined or null array items are converted into '' or empty string.

## slice vs splice

Both are used to return a sub-array but..

```javascript
const myArr = [1,2,3,4,5,6]

const subArr1 = myArr.slice(1,3)
console.log(subArr1)                // [ 2, 3 ]
console.log(myArr)  // [ 1, 2, 3, 4, 5, 6 ]

const subArr2 = myArr.splice(1,3)
console.log(subArr2)                // [2, 3, 4 ]
console.log(myArr)  //  [ 1, 5, 6 ]
```

**Key Differences:**

*   in `.slice(start, end)` we take sub array from start to end - 1 (exclusive), in splice we take the end as well.
    
*   in slice we do not modify the original array, in splice we delete the subarray from the original array.
    

As slice doesn't mutate the original array and returns a new copy hence it is frequently used to swallow-copy other arrays without reference.

```javascript
const letters = ['a','b','c','d','e']

const copyLetters = letters.slice()
copyLetters[0] = 'z'

console.log(letters)      
// [ 'a', 'b', 'c', 'd', 'e' ]
console.log(copyLetters)
// [ 'z', 'b', 'c', 'd', 'e' ]
```

## Merging two arrays

let's try .push()

```javascript
const marvel_heros = ["thor", "Ironman", "spiderman"]
const dc_heroes = ["superman", "flash", "batman"]

marvel_heros.push(dc_heroes)

console.log(marvel_heros)
```

Output

```plaintext
[ 'thor', 'Ironman', 'spiderman', [ 'superman', 'flash', 'batman' ] ]
```

so push doesn't really work it pushes the entire array as to the last element, causing it to become a array of array.

```javascript
console.log(marvel_heros[3][1])    // flash
```

This is how we will need to obtain items from an array inside an array, but this isn't ideal.

### concat

concat returns a joined array but doesn't manipulate any existing array.

```javascript
const marvel_heros = ["thor", "Ironman", "spiderman"]
const dc_heroes = ["superman", "flash", "batman"]

const heroes = marvel_heros.concat(dc_heroes)
console.log(heroes)    // [ 'thor', 'Ironman', 'spiderman', 'superman', 'flash', 'batman' ]
```

### spread

spread makes the items come out of the array at once as separate items.

\["thor", "Ironman", "spiderman"\] -> "thor" "Ironman" "spiderman"

```javascript
const marvel_heros = ["thor", "Ironman", "spiderman"]
const dc_heroes = ["superman", "flash", "batman"]

const heroes = [...marvel_heros, ...dc_heroes]
console.log(heroes)    // [ 'thor', 'Ironman', 'spiderman', 'superman', 'flash', 'batman' ]
```

Spread operator can also be used to copy another array just like slice.

## flat

We use flat when there are elements inside an array that are array and maybe even inside that, If we want to convert the whole thing into one single array.

```javascript
const arr = [1,2,3,[4,5,6],7,[6,7,[4,5]]]

console.log(arr.flat(1))
console.log(arr.flat(Infinity))
```

Output

```plaintext
[ 1, 2, 3, 4, 5, 6, 7, 6, 7, [ 4, 5 ] ]
[
  1, 2, 3, 4, 5,
  6, 7, 6, 7, 4,
  5
]
```

Inside the method argument we can specify how deep we want to go.

## isArray

Since typeof any array returns object always use the `Array.isArray()` to check if variable is really an array.

```javascript
console.log(typeof [1,2,3])            // object
console.log(Array.isArray([1,2,3]))    // true
console.log(Array.isArray("AI"))       // false
```

## from and of

`Array.from(value)` is used to convert iterable objects into array. Returns an empty array if it cannot convert.

```javascript
console.log(Array.from("gabit"))            // [ 'g', 'a', 'b', 'i', 't' ]
console.log(Array.from({name: "gambit"}))   // []
const arrayLike = {
  0: "Gray",
  1: "White",
  2: "Pink",
  length: 2
};

const colors = Array.from(arrayLike);
console.log(colors); // ["Gray", "White"]
```

In case of objects it only converts 'Array like' objects, basically objects that have a length property.

`Array.of(var1,var2,...)` It returns a new array from a set of elements

```javascript
let a = 100
let b = "200"
let c = [0, 0, 1, 0]

console.log(Array.of(a,b,c)) // [ 100, '200', [ 0, 0, 1, 0 ] ]
```

## Higher Order Functions

If you pass a function as a argument inside another function while calling it becomes a higher order function.

```javascript
function addingForty(something){
    return something() + 40
}

function returnTen(){
    return 10
}

console.log(addingForty(returnTen)). // 50
```

## Sort() and toSorted()

Sorting an array in ascending and descending order.

```javascript
const nums = [100, 25, 3, 42, 8]

const ascendingNums = [...nums].sort((a,b) => a - b)
const descendingNums = [...nums].sort((a,b) => b - a)

console.log(ascendingNums)
// [ 3, 8, 25, 42, 100 ]
console.log(descendingNums)
// [ 100, 42, 25, 8, 3 ]
```

`sort()` changes the original array in place, whereas `toSorted()` leaves the original untouched and returns a brand-new sorted copy.
