# 陣列的各種操作方法
<div class="block">
**操作陣列可以先區分為兩大類:**
[`會改變原始陣列長相`](#會改變原始陣列)與[`複製一個原始陣列來更改`](#不改變原始陣列,產生新的陣列)
</div>

<small>*陣列圖片來源:[偷米騎巴哥]操作JS陣列的20種方式*</small>
---
## 不改變原始陣列,產生新的陣列
`.map` `.filter` `.slice` `concat`
### ➤ `.map(function(item, index, array) {return }` 產生一個新陣列
- 與 [forEach](#➤-forEachfunctionitem-index-array-迴圈) 非常類似
- map 會 return 一個值,並且**新產生一個陣列**
- map 跟 filter 不同的是: map 可以去做處理並返回
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
let any2 = any.map(function(item, index, array) {
return item + item;
})
console.log(any2);
// ["AA", "BB", "CC", "DD", "EE"]
console.log(any);
// ["A", "B", "C", "D", "E"]
```
:::info
Map 不會對原有的陣列受到任何影響
:::
- 範例三:組合人名第一個字與最後一個字

字串空格

或是用 eslint

console

---
### ➤ `.filter(function(item 當前的值, index, array) {return }` 篩選
- `.filter(function(item, index, array) {return }`
- `item` 物件值
- `index` 陣列索引
- `array` 陣列本身
- 原有的陣列 any 不會受到影響
- map 跟 filter 不同的是: filter
- 作法與 forEach 類似
- ex: 挑出偶數
```javascript=
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let newAny = any.filter(function(item) {
return item % 2 === 0;
// 可以被2整除並等於0的就代表偶數。
})
console.log(newAny)
// [2, 4, 6, 8, 10]
```
- 挑出基數
```javascript=
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
any.filter(function(item) {
return item % 2 !== 0;
// 不能被2整除並不等於0的就代表基數。
})
// [1, 3, 5, 7, 9]
```
```javascript=
[1, 2, 3].filter((item, index, arr) => {
arr[i + 1] > 2;
});
// arr[0+1] => arr[1]取出陣列第一位 2 > 2 ? false
// arr[1+1] => arr[2]取出陣列第二位 3 > 2 ? true
// arr[2+1] => arr[3]取出陣列第三位 undefined > 2 ? false
// 丟出 true 的結果
// 回傳 2
```
- 範例三 :找出 1500 年代的人


tips:`console.table`

---
### ➤ `.slice(begin, end)` 取得範圍
- 與 [`splice`](#➤-splice-刪除與塞入資料特定位置) 有點類似
- 取得範圍,但是 slice 可以從特定範圍變成一個新陣列
- 原陣列選擇之<font color="red"> begin 至 end(不含 end)</font>部分的淺拷貝(shallow copy)。而原本的陣列將不會被修改。
- `begin 選擇性` 自哪一個索引(起始為 0)開始提取拷貝
- 可以使用負數索引
- begin 為 undefined,則 slice 會從索引 0 開始提取
- `end 選擇性`
- 至哪一個索引(起始為 0)之前停止提取。
- 不包含 end
- 可使用負數索引,表示由陣列的最末項開始提取
- 省略 end,則 slice 會提取至陣列的最後一個元素
- end 大於陣列的長度,slice 也會提取至陣列的最後一個元素
```javascript=
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
any.slice(4, 9);
// [5, 6, 7, 8, 9]
// 從 [4]~[9] 不包含第九的索引值,所以沒有 10
```
- 範例: 複製一份原有的
```javascript=
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let a = any.slice(0);
console.log(a);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a.push("9");
console.log(a);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "9"]
```
> [MDN: Array.prototype.slice()](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
---
### ➤ `.concat([連接陣列])` 相連
- 兩個陣列要串接再一起就要使用 concat
- 對原有的陣列不影響
```javascript=
any = ['A', 'B'];
any.concat(['C', 'D', 'E']);
// ['A', 'B', 'C', 'D', 'E']
```
## 會改變原始陣列
### ➤ `.shift()` 拿取出第一個
- <font color="red">拿出陣列中第一筆資料</font>
- .shift() 是`不用帶參數`
```javascript=
ary = [1, 2, 3, 4];
console.log(ary.shift()); // 1
console.log(ary); // [2, 3, 4]
```
### ➤ `.unshift(parameter)` 放回去第一個
- <font color="red">放回去陣列中第一筆資料</font>
```javascript=
ary = [2, 3, 4];
console.log(ary.unshift(1)); // 現在有 4 筆資料
console.log(ary); // [1, 2, 3, 4]
```
---
### ➤ `.pop()` 拿取出最後一個
- <font color="red">拿出陣列中最後一筆資料</font>
- .pop() 是`不用帶參數`
```javascript=
ary = [1, 2, 3, 4];
console.log(ary.pop()); // 4
console.log(ary); // [1, 2, 3]
```
### ➤ `.push(parameter)` 放回去最後一個
- <font color="red">放回去陣列中最後一筆資料</font>
```javascript=
ary = [1, 2, 3];
console.log(ary.push(4)); // 現在有 4 筆資料
console.log(ary); // [1, 2, 3, 4]
```
---
### ➤ `.splice()` 刪除與塞入資料特定位置
1. <font color="red">取出(刪除)</font>陣列特定位置
- `splice(start,deleteContent)` 可以帶入2個參數
- `start` 索引位置(從 0 開始)
- `deleteContent` 刪除幾筆資料量 或 取出幾筆資料量
```javascript=
ary = ['A', 'B', 'C', 'D', 'E', 'F'];
console.log(ary.splice(2,1));
// 索引值第二、刪除一筆
// ['C']
console.log(ary);
// ['A', 'B', 'D', 'E', 'F']
```
- `splice(start)` 從索引值開始刪到最後
```javascript=
ary = ['A', 'B', 'C', 'D', 'E', 'F'];
console.log(ary.splice(2));
// ['C', 'D', 'E', 'F']
console.log(ary);
// ['A', 'B']
```
2. <font color="red">塞回</font>陣列特定位置
- `splice(start,0 , 要加入的值)`
- 第二個參數帶入 `0` ,這樣就不會刪掉陣列中的值
```javascript=
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = myFish.splice(2, 0, 'drum');
// myFish 為 ["angel", "clown", "drum", "mandarin", "sturgeon"]
// removed 為 [], 沒有元素被刪除
```
---
### ➤ `sort` 針對陣列去做排序
- 透過 `function return` 帶入兩個參數
:::info
sort 可以做排序,但是是使用<font color='red'>字串</font>去做排序,
所以如果要針對數字排序,就要記得帶入 function,
:::
```javascript=
any = [14, 30, 35, 42, 5, 16, 70, 98, 19, 100];
any.sort(function(a, b) {
return a > b ? 1 : -1;
// return a < b ? 1 : -1; 可得到由大到小排序
});
console.log(any);
// [5, 14, 16, 19, 30, 35, 42, 70, 98, 100]
```
```javascript=
any = [14, 30, 35, 42, 5, 16, 70, 98, 19, 100];
any.sort(function(a, b) {
return a - b;
// return b - a; 可得到由大到小排序
});
console.log(any);
// [5, 14, 16, 19, 30, 35, 42, 70, 98, 100]
```
- 排列生日,從大到小

帶入兩個人去比較 a b
return 1
return -1
排列上與下的順序


### ➤ `.reverse()` 倒序
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
any.reverse();
console.log(any);
// ['E', 'D', 'C', 'B', 'A']
```
---
### ➤ `.length`
- 讀取陣列資料、了解陣列長度
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
console.log(any.length);
// 5
```
- **改變陣列**
- ex: 將陣列給清空
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
any.length = 0;
console.log(any);
// []
```
- ex: 只保留陣列 2 筆資料
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
any.length = 2;
console.log(any);
// ['A', 'B']
```
---
### ➤ `.toString()` 陣列轉字串
- 陣列轉換成字串,中間會加上 `,` 隔開
```javascript=
ary = [2, 3, 4, 3,2];
ary.toString();
// "2,3,4,3,2"
```
### ➤ `.join('可自定符號')` 陣列轉字串
- 陣列轉換成字串,預設中間會加上 `,` 隔開
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
any.join();
// "A,B,C,D,E"
```
- <font color="red">**可自定除了逗號以外的符號**</font>
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
any.join('_');
// "A_B_C_D_E"
```
- 帶入空字串
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
any.join('');
// "ABCDE"
```
---
### ➤ `.reduce(function(prev, next){ return}, 初始值)` 累加
- 第一累加到最後一筆
:::info
- reduce 是**必須帶入 function,而這 function 通常會帶入兩個參數,通常會叫 prev (前一個), next (後一個)**
- reduce 必須回傳 (`return`),否則會出現 undefined
:::
```javascript=
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
any.reduce(function(prev, next){
return prev + next;
});
// 55
```
- 帶入的是 字串 會變成字串組合
```javascript=
any = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
any.reduce(function(prev, next){
return prev + next;
});
// "12345678910"
```
- 範例:年份加起來總共幾年

這個 array 可以看到一個 inventor 是從 year 到 passed ,所以想要知道經過多久時間,可以 `passed - year`(ex: 1955-1879)
0 是累加的初始值,一開始這個 total 是自己設定的,所以要給一個初始才會繼續往上加

### ➤ `.reduceRight(function(prev, next){ return})`
- 最後一筆累加到第一筆
:::info
通常若使用數字來累積是看不出差異的
:::
```javascript=
any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
any.reduceRight(function(prev, next){
return prev + next;
});
// 55
// 跟 reduse 得到的答案是一樣的
```
- 字串可以看出差異性
```javascript=
any = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
any.reduceRight(function(prev, next){
return prev + next;
});
// "10987654321"
```
---
### ➤ `.indexOf('搜尋的值')` 搜尋陣列的索引位置
- **一找到資料就會立刻回傳**
- indexOf索引是從 0 開始
- 陣列裡若無該值,會回傳 `-1`
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
any.indexOf('B');
// 1
// A位子代表 0,B則為 1
any.indexOf('J');
// -1
```
### ➤ `.lastIndexOf('搜尋的值')` 搜尋陣列的索引位置
- **全部陣列找完,再回傳`最後一筆資料`索引位子**
```javascript=
any = ['A', 'B', 'A', 'D', 'A'];
any.indexOf('A');
// 0
// 此時會發現indexOf會回傳他第一個找到的A
any.lastIndexOf('A');
// 4
// lastIndexOf他會找到最後一筆,所以最後一筆A在陣列索引4
```
### ➤ `findIndex()` 檢查陣列
- 比對陣列元素,回傳 `索引值`
```javascript=
const arr=[1,2,3,4,5]
console.log(arr.findIndex(function(e){return e===1}))
// 0
```
- findIndex()括號裡面是放函式
- 查找範圍
```javascript=
const arr=[1,2,3,4,5]
console.log(arr.findIndex(function(e){return e>1}))
//找到2這個元素,並回傳2的索引號1
```
- findIndex()裡面放元素的話,會無法執行
---
### ➤ `.some(function(){})` 一個滿足條件,即回傳 true
- 檢查陣列中的結果是否相同
- 有一個符合結果相同就會回傳 ture
- function ... return
```javascript=
any = ['C', 'B', 'C', 'C', 'C'];
any.some(function(val) {
return val === 'C'
});
// true
```
### ➤ `.every(function(){})` 全部都要滿足條件,才會回傳 true
- 陣列每一個都符合時就會回傳 true
```javascript=
any = ['C', 'B', 'C', 'C', 'C'];
any.every(function(val) {
return val === 'C'
});
// false
```
- 檢查每一個**字串裡的長度**
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
any.every(function(val) {
return val.length === 1;
});
// true
any = ['A1', 'Bw', 'aC', 'dD', 'aE'];
any.every(function(val) {
return val.length === 2;
});
// true
```
---
### ➤ `.forEach(function(item, index, array){})` 迴圈
- <span class='bg-b'>ES6 </span>
- `.forEach(function(item, index, array){}` 可以帶入三個參數(參數名稱可自定義):
- `item` 物件值
- `index` 陣列索引
- `array` 陣列本身
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
any.forEach(function(item, index, array) {
console.log(item, index, array);
})
// A 0 (5) ["A", "B", "C", "D", "E"]
// B 1 (5) ["A", "B", "C", "D", "E"]
// C 2 (5) ["A", "B", "C", "D", "E"]
// D 3 (5) ["A", "B", "C", "D", "E"]
// E 4 (5) ["A", "B", "C", "D", "E"]
```
- 範例:陣列判斷取出,並放入另一個物件中。且透過 forEach 與 innerHTML 整合,一次渲染多筆資料在網頁上
<iframe height="300" style="width: 100%;" scrolling="no" title="8/23 (一) - 陣列 forEach 寫法" src="https://codepen.io/unayo/embed/dyRyENN?default-tab=js&theme-id=dark" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/unayo/pen/dyRyENN">
8/23 (一) - 陣列 forEach 寫法</a> by unayo (<a href="https://codepen.io/unayo">@unayo</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
- 範例二: forEach 與 整合 innerHTML 資料
<iframe height="300" style="width: 100%;" scrolling="no" title="8/24 (二) - 如何整合 innerHTML 資料" src="https://codepen.io/unayo/embed/oNwNrYq?default-tab=js%2Cresult&theme-id=dark" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/unayo/pen/oNwNrYq">
8/24 (二) - 如何整合 innerHTML 資料</a> by unayo (<a href="https://codepen.io/unayo">@unayo</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
### ➤ for loop
- forEach 簡化了 for loop
```javascript=
any = ['A', 'B', 'C', 'D', 'E'];
for (let i = 0; i < any.length; i++){
console.log(any[i],i); // i 代表索引值
}
// A 0
// B 1
// C 2
// D 3
// E 4
```
---
###### tags: `JS`
{%hackmd @unayojanni/H1Qq0uKkK %}
> 參考:
> [[偷米騎巴哥]操作JS陣列的20種方式](https://www.youtube.com/watch?v=x-P1VxUgYG4&ab_channel=%E5%81%B7%E7%B1%B3%E9%A8%8E%E5%B7%B4%E5%93%A5)
> [Ray 的操作陣列的20種方式](https://hsiangfeng.github.io/javascript/20190421/1216566123/)
總彙整:陣列與物件整合運用
<iframe height="300" style="width: 100%;" scrolling="no" title="8/4 ,5,6 - 陣列、物件宣告、取值、新增" src="https://codepen.io/unayo/embed/PomdZjE?default-tab=js&theme-id=dark" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/unayo/pen/PomdZjE">
8/4 ,5,6 - 陣列、物件宣告、取值、新增</a> by unayo (<a href="https://codepen.io/unayo">@unayo</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
###### tags: `JS`
{%hackmd @unayojanni/H1Qq0uKkK %}