# 陣列的各種操作方法 <div class="block"> **操作陣列可以先區分為兩大類:** [`會改變原始陣列長相`](#會改變原始陣列)與[`複製一個原始陣列來更改`](#不改變原始陣列,產生新的陣列) </div> ![](https://i.imgur.com/eAnmTS9.jpg) <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 不會對原有的陣列受到任何影響 ::: - 範例三:組合人名第一個字與最後一個字 ![](https://i.imgur.com/W1yXbrP.png) 字串空格 ![](https://i.imgur.com/VhfGBFj.png) 或是用 eslint ![](https://i.imgur.com/nd0RLc8.png) console ![](https://i.imgur.com/ppCjBoV.png) --- ### ➤ `.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 年代的人 ![](https://i.imgur.com/wJ3PEhY.png) ![](https://i.imgur.com/3uw6yj5.png) tips:`console.table` ![](https://i.imgur.com/xaxUv2k.jpg) --- ### ➤ `.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] ``` - 排列生日,從大到小 ![](https://i.imgur.com/G2xBvYy.png) 帶入兩個人去比較 a b return 1 return -1 排列上與下的順序 ![](https://i.imgur.com/pz5jozl.png) ![](https://i.imgur.com/mpIX0Hm.png) ### ➤ `.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" ``` - 範例:年份加起來總共幾年 ![](https://i.imgur.com/dIG2hBb.png) 這個 array 可以看到一個 inventor 是從 year 到 passed ,所以想要知道經過多久時間,可以 `passed - year`(ex: 1955-1879) 0 是累加的初始值,一開始這個 total 是自己設定的,所以要給一個初始才會繼續往上加 ![](https://i.imgur.com/0tg1PKv.png) ### ➤ `.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 %}