# Array methods

## Add/remove items

* `arr.push(...items)` – adds items to the end,
* `arr.pop()` – extracts an item from the end,
* `arr.shift()` – extracts an item from the beginning,
* `arr.unshift(...items)` – adds items to the beginning.

### splice 插入、移除、替換 array 的值

```javascript
// array 可以使用 delete 刪除值，但屬性仍然存在
let arr = ["I", "go", "home"];
delete arr[1]; // remove "go"
alert( arr[1] ); // undefined
// now arr = ["I",  , "home"];
alert( arr.length ); // 3

// splice
arr.splice(index[, deleteCount, elem1, ..., elemN])

// delete
let arr = ["I", "study", "JavaScript"];
arr.splice(1, 1); // from index 1 remove 1 element
alert( arr ); // ["I", "JavaScript"]

// replace
let arr = ["I", "study", "JavaScript", "right", "now"];
// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");
alert( arr ) // now ["Let's", "dance", "right", "now"]

// splice 返回移除的值
let arr = ["I", "study", "JavaScript", "right", "now"];
// remove 2 first elements
let removed = arr.splice(0, 2);
alert( removed ); // "I", "study" <-- array of removed elements

// insert
let arr = ["I", "study", "JavaScript"];
// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");
alert( arr ); // "I", "study", "complex", "language", "JavaScript"

// 可以用負數 index
let arr = [1, 2, 5];
// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);
alert( arr ); // 1,2,3,4,5
```

### slice 返回複製指定位置新的 array

```javascript
arr.slice(start, end)

let str = "test";
let arr = ["t", "e", "s", "t"];

alert( str.slice(1, 3) ); // es
alert( arr.slice(1, 3) ); // e,s

alert( str.slice(-2) ); // st
alert( arr.slice(-2) ); // s,t
```

### concat 串聯 array 或值

```javascript
arr.concat(arg1, arg2...)

let arr = [1, 2];
// merge arr with [3,4]
alert( arr.concat([3, 4])); // 1,2,3,4
// merge arr with [3,4] and [5,6]
alert( arr.concat([3, 4], [5, 6])); // 1,2,3,4,5,6
// merge arr with [3,4], then add values 5 and 6
alert( arr.concat([3, 4], 5, 6)); // 1,2,3,4,5,6

// caoncat 複製 array 中的元素，但若對像不是 array 會複製全部加上去
let arr = [1, 2];
let arrayLike = {
  0: "something",
  length: 1
};
alert( arr.concat(arrayLike) ); // 1,2,[object Object]
//[1, 2, arrayLike]

// 如果對象有 Symbol.isConcatSpreadable 屬性，只會複製元素加上去
let arr = [1, 2];
let arrayLike = {
  0: "something",
  1: "else",
  [Symbol.isConcatSpreadable]: true,
  length: 2
};
alert( arr.concat(arrayLike) ); // 1,2,something,else
```

## Iterate: forEach

`arr.forEach(func())` 將 array 中所有元素帶入函式內。

```javascript
arr.forEach(function(item, index, array) {
  // ... do something with item
});

// for each element call alert
["Bilbo", "Gandalf", "Nazgul"].forEach(alert);

["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
  alert(`${item} is at index ${index} in ${array}`);
});
```

## Searching in array

### indexOf/lastIndexOf and includes

* `arr.indexOf(item, from)` looks for `item` starting from index `from`, and returns the index where it was found, otherwise `-1`.
* `arr.lastIndexOf(item, from)` – same, but looks for from right to left.
* `arr.includes(item, from)` – looks for `item` starting from index `from`, returns `true` if found.

```javascript
let arr = [1, 0, false];
alert( arr.indexOf(0) ); // 1
alert( arr.indexOf(false) ); // 2
alert( arr.indexOf(null) ); // -1

alert( arr.includes(1) ); // true

// use ===
const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (should be 0, but === equality doesn't work for NaN)
alert( arr.includes(NaN) );// true (correct)
```

### find and findIndex 若 array 的元素是物件，要找到特定物件用 find，只返回第一個符合函示元素。

* `item` is the element.
* `index` is its index.
* `array` is the array itself.

```javascript
let result = arr.find(function(item, index, array) {
  // if true is returned, item is returned and iteration is stopped
  // for falsy scenario returns undefined
});

let users = [
  {id: 1, name: "John"},
  {id: 2, name: "Pete"},
  {id: 3, name: "Mary"}
];
let user = users.find(item => item.id == 1);
alert(user.name); // John
```

filter 跟 find 很像，但會返回所有符合函式的元素。

```javascript
let results = arr.filter(function(item, index, array) {
  // if true item is pushed to results and iteration continues
  // returns empty array for complete falsy scenario
});

let users = [
  {id: 1, name: "John"},
  {id: 2, name: "Pete"},
  {id: 3, name: "Mary"}
];
// returns array of the first two users
let someUsers = users.filter(item => item.id < 3);
alert(someUsers.length); // 2
```

## Transform an array

### map  將 array 每個元素帶入函式並返回新的 array

```javascript
let result = arr.map(function(item, index, array) {
  // returns the new value instead of item
})

let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6
```

### sort(fn)&#x20;

```javascript
// sort 依照 string 排序
let arr = [ 1, 2, 15 ];
// the method reorders the content of arr (and returns it)
arr.sort();
alert( arr );  // 1, 15, 2

// 要用自定義的函式當參數
function compareNumeric(a, b) {
  if (a > b) return 1;
  if (a == b) return 0;
  if (a < b) return -1;
}

let arr = [ 1, 2, 15 ];
arr.sort(compareNumeric);
alert(arr);  // 1, 2, 15

// 比較函式返回正數代表較大，返回負數代表較小
let arr = [ 1, 2, 15 ];
arr.sort(function(a, b) { return a - b; });
alert(arr);  // 1, 2, 15

// 更短的寫法
arr.sort( (a, b) => a - b );
```

### reverse

```javascript
let arr = [1, 2, 3, 4, 5];
arr.reverse();

alert( arr ); // 5,4,3,2,1
```

### split and join 將 string 用符號分開成 array / 將 array 用符號連接成 string

```javascript
// str.split()
let names = 'Bilbo, Gandalf, Nazgul';
let arr = names.split(', ');
for (let name of arr) {
  alert( `A message to ${name}.` ); // A message to Bilbo  (and other names)
}

// 第 2 個參數指定返回 array 的長度
let arr = 'Bilbo, Gandalf, Nazgul, Saruman'.split(', ', 2);
alert(arr); // Bilbo, Gandalf

// 空字串返回字母組成的 array
let str = "test";
alert( str.split('') ); // t,e,s,t

// arr.join()
let arr = ['Bilbo', 'Gandalf', 'Nazgul'];
let str = arr.join(';');
alert( str ); // Bilbo;Gandalf;Nazgul
```

### reduce/reduceRight&#x20;

* `previousValue` – is the result of the previous function call, `initial` for the first call.
* `item` – is the current array item.
* `index` – is its position.
* `array` – is the array.

```javascript
let value = arr.reduce(function(previousValue, item, index, array) {
  // ...
}, initial);

let arr = [1, 2, 3, 4, 5];
let result = arr.reduce((sum, current) => sum + current, 0);
alert(result); // 15
```

![](https://2384301684-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LS3vj0v55HiJ9Pkdigx%2F-LhYdKQp3Z2Xr0-SZ1y-%2F-LhYe2kuTvjR5N9MnNOF%2Freduce%402x.png?alt=media\&token=21d915ad-064a-4859-ba81-c88dffa9a6a0)

|                 | `sum` | `current` | `result` |
| --------------- | ----- | --------- | -------- |
| the first call  | `0`   | `1`       | `1`      |
| the second call | `1`   | `2`       | `3`      |
| the third call  | `3`   | `3`       | `6`      |
| the fourth call | `6`   | `4`       | `10`     |
| the fifth call  | `10`  | `5`       | `15`     |

```javascript
// same
let arr = [1, 2, 3, 4, 5];
// removed initial value from reduce (no 0)
let result = arr.reduce((sum, current) => sum + current);
alert( result ); // 15

// error if array is empty so suggest to set intial value 
let arr = [];
// Error: Reduce of empty array with no initial value
// if the initial value existed, reduce would return it for the empty arr.
arr.reduce((sum, current) => sum + current);
```

## Array.isArray

```javascript
alert(typeof {}); // object
alert(typeof []); // same

alert(Array.isArray({})); // false
alert(Array.isArray([])); // true
```

## Most methods support “thisArg”

```javascript
// 很少用到 thisArg
arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
// ...
// thisArg is the optional last argument

// thisArg 代表函式中用到的 this
let user = {
  age: 18,
  younger(otherUser) {
    return otherUser.age < this.age;
  }
};
let users = [
  {age: 12},
  {age: 16},
  {age: 32}
];
// find all users younger than user
let youngerUsers = users.filter(user.younger, user);
alert(youngerUsers.length); // 2
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mistborn.gitbook.io/til-coding/javascript/array-methods.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
