Array 有哪些操作方法

剛寫 javascript 的時候,永遠只會用 forEach 一招打到底,某天看了線上課程,才發現有 some、findIndex、every 這些陌生面孔,能夠縮短不少程式碼(懶人福音),因此想要寫一篇關於陣列的操作方法筆記。

includes

以前要判斷陣列裡面是否含有某個特定元素,習慣用 indexOf 來處理,現在用 includes 就直覺方便了,有包含的話就會 return true!

1
2
3
4
5
6
7
8
9
10
11
//before
let array = ["one", "two", "three"];
let target = "two";
if (array.indexOf(target) > -1) {
//do next
}

//after
if (array.includes(target)) {
//do next
}

indexOf(value)

尋找目標對象在陣列中的索引值,如果找不到的話就會回傳-1

1
memberList.indexOf("Jack"); //1

lastIndexOf(value)

取指定對象最後一個出現的索引值,如果找不到的話就會回傳-1

1
2
3
let student = ["Tom", "Marry", "Waston", "Tom"];
let lastPosition = student.lastIndexOf("Tom");
console.log(lastPosition); //3

slice

1
slice(begin, end);
  • begin : 起始的 index ,若為-1 則代表從倒數第一個開始算
  • end: 結束的 index ,若不填則代表選取到陣列最後一個元素
1
2
3
4
5
6
7
8
let list = ["green", "olive", "steelblue", "yellow"];
let target = list.slice(0, 2);
console.log(target);
//output: ["green", "olive"]
let all = list.slice(0);

console.log(all);
//output: ["green", "olive", "steelblue", "yellow"]

splice

1
splice(begin, deleteCount, addItem);
  • begin: 起始 index 若為-1,則代表從倒數第一個開始算
  • deleteCount: 要刪除的個數
  • addItem: 要添加的元素

當陣列經過 splice 的處理之後,原陣列也會跟著改變。

1
2
3
4
5
6
7
8
let list = ["green", "olive", "steelblue", "yellow"];
let newArr = list.splice(0, 2, "lightPink");
console.log(newArr);
//output: ["lightPink", "steelblue", "yellow"]

let target = list.slice(1, 2);
console.log(target);
//output: ["olive", "steelblue"]

forEach

大家最熟悉的 forEach,遍歷的好朋友,年輕不懂事的時候在裡面寫 return 結果美丁美當,那個…要 return 值的話請用 map

1
2
3
4
5
6
7
8
9
10
11
12
13
let list = ["green", "olive", "steelblue"];
let arr = [];
list.forEach((item) => {
arr.push(item);
});
console.log(data);
//output: ['green','olive','steelblue']

let data = list.forEach((vo) => {
return vo;
});
console.log(data);
//output: undefined

map

1
2
3
4
5
6
7
8
9
10

工廠的概念,陣列的元素會被逐一加工,最後返回一個全新的陣列。

let student = ['Tom',Marry','Waston','Petter']
let result = student.map(item =>{
return `**${item}**`
})
console.log(result)
//output :['**Tom**', '**Marry**', '**Waston**', '**Petter**']

filter

過濾符合條件想要篩選出來的對象,若沒有則回傳空陣列

1
2
3
4
5
6
7
8
let family = ["Tom", "Marry", "Waston", "Petter"];
let res = family.filter((item) => {
//搜尋誰的名字裡含有"o"的
return item.includes("o");
});

console.log(res);
//output: ['Tom', 'Waston']

find

一開始我以為他跟 filter 差不多,但實際上 filter 可以回傳一個陣列包含多個符合條件的對象,find 則是只能回傳第一個符合條件的項目,沒有的話則 return undefined

1
2
3
4
5
6
7
let family = ["Tom", "Marry", "Waston", "Petter"];
let = family.find((item) => {
//搜尋誰的名字是"n"結尾的
return item.endsWith("n");
});
console.log(res);
//output: 'Waston'

toString

其實我一直不知道 array 有這個方法…都是習慣用 join()

1
2
3
4
let family = ["Tom", "Marry", "Waston", "Petter"];
let str = family.toString();
console.log(str);
//output: 'Tom,Marry,Waston,Petter'

join

將陣列裡的項目組成字串,可指定間隔字串

1
2
3
4
let family = ["Tom", "Marry", "Waston", "Petter"];
let str = family.join("!");
console.log(str);
//output:"Tom!Marry!Waston!Petter"

isArray

判斷是否為陣列

1
2
3
4
let list = ["tea", "soda", "water"];
var res = Array.isArray(list);
console.log(res);
//output: true

some

是否部份符合條件,只要有一個對象符合 就 return true

1
2
3
4
5
6
let list = ["tea", "soda", "water"];
let res = list.some((item) => {
return item.length >= 5; //是否項目的長度大於 5
});
console.log(res);
//output: true

every

陣列的每一個項目是否符合條件,只要有一個對象不符合,就 return false

1
2
3
4
5
6
let list = ["tea", "soda", "water"];
let res = list.every((item) => {
return item.length == 3; //是否每個項目的長度
});
console.log(res);
//output: false

findIndex

尋找目標對象的 index

1
2
3
4
5
6
let student = ["Tom", "Marry", "Waston", "Tom"];
let res = student.findIndex((item) => {
return item == "Marry";
});
conole.log(res);
//output: 1

lastIndexOf

取指定對象最後一個出現的位置的 index ,好比是隊伍中排了三隻小火龍,我們取最後一隻出現的 index。

1
2
3
4
let student = ["Tom", "Marry", "Waston", "Tom"];
let lastPosition = student.lastIndexOf("Tom");
console.log(lastPosition);
//output: 3

sort

將陣列由小到大排序,字母的話按照 a-z,如果沒有帶入 function,就會將陣列每個項目轉換成字串來比對,不過這裡就會發現一個問題,為甚麼 300 會排在 55 的前面?因為以比對字串來說,300 的「3」小於 55 的「5」,因此才會出現 300 比 55 還小的這種詭異情形。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let family = ["Tom", "Marry", "Waston", "Petter"];
let list = family.sort();
console.log(list);
//output: ['Marry', 'Tom', 'Tom', 'Waston']

let num = [12, 25, 55, 300];
let order = num.sort();
console.log(order);
//output: [12, 25, 300, 55]

//由大到小排列
num.sort((prev, next) => next - prev);
console.log(num);
//output: [300, 55, 25, 12]

//由小到大排列
num.sort((prev, next) => prev - next);
console.log(num);
//output: [12, 25, 55, 300]

reverse

反轉陣列的順序

1
2
3
4
let member = ["Tom", "Marry", "Waston", "Petter"];
let res = member.reverse();
console.log(res);
//output: ['Petter', 'Waston', 'Marry', 'Tom']

concat

將多個陣列串聯成同一個陣列

1
2
3
4
5
6
let teamA = ["Tom", "Marry", "Waston", "Petter"];
let teamB = ["Kevin", "Joe", "Vicky", "Roy"];

let teamAll = teamA.concat(teamB);
console.log(teamAll);
//output: ["Tom", "Marry", "Waston", "Petter", "Kevin", "Joe", "Vicky", "Roy"]

keys

獲得一個陣列的所有 key,也就是 index

1
2
3
4
let student = ["Tom", "Marry", "Waston", "Tom"];
let num = keys(student);
console.log(num);
//output: [0,1,2,3]

valueOf

可以複製一個新陣列,但這邊實際測試如果修改 newArr 的值,其實 student 也會改變

1
2
3
4
let student = ["Tom", "Marry", "Waston", "Tom"];
let newArr = student.valueOf();
console.log(newArr);
//output: ['Tom','Marry','Waston','Petter']

fill

填滿的概念,把大家通通變成指定的形狀(?),會改變原本的陣列

1
2
3
4
let student = ["Tom", "Marry", "Waston", "Tom"];
var res = student.fill("shane");
console.log(res);
//output: ['shane', 'shane', 'shane', 'shane']

reduce

將陣列的元素傳入 callback 處理,最後陣列會化作單一值,這邊引用了 MDN 的說明。

1
2
3
4
array.reduce(
callback(accumulator, currentValue, currentIndex, arr),
initialValue
);
  • accumulator

用來累積回呼函式回傳值的累加器(accumulator)或 initialValue。累加器是上一次呼叫後,所回傳的累加數值。

  • currentValue

原陣列目前所迭代處理中的元素。

  • currentIndex (非必填

原陣列目前所迭代處理中的元素之索引。若有傳入 initialValue,則由索引 0 之元素開始,若無則自索引 1 之元素開始。

  • array(非必填

呼叫 reduce() 方法的陣列。

  • initialValue(非必填)

於第一次呼叫 callback 時要傳入的累加器初始值。若沒有提供初始值,則原陣列的第一個元素將會被當作初始的累加器。假如於一個空陣列呼叫 reduce() 方法且沒有提供累加器初始值,將會發生錯誤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let array = [1, 2, 3, 4];
let reducer = (accumulator, currentValue) => accumulator + currentValue;

// 1 + 2 + 3 + 4
console.log(array.reduce(reducer));
// expected output: 10

// 5 + 1 + 2 + 3 + 4
console.log(array.reduce(reducer, 5));
// expected output: 15

因此用 reduce 來找陣列裡面最大或是最小的數字也是很方便的

let array = [1, 2, 3, 4];
let res = array.reduce((accumulator, currentValue)=>{
return Math.max(accumulator, currentValue)
})
console.log(res)
//output: 5

reduceRight

跟 reduce 差不多,不過順序變成由右至左,如果是做數字加總那結果是一樣的,如果是組字串那就可以看得出差異。

1
2
3
4
5
6
7
8
9
10
let array = ["a", "b", "c", "d", "e"];
let left = array.reduce((prev, cur) => {
return prev + cur;
});
let right = array.reduceRight((prev, cur) => {
return prev + cur;
});

console.log(left); // output: "abcde"
console.log(right); // output: "edcba"

entries

回傳陣列中每組(key, value)迭代器(Iterator)

1
2
3
4
5
6
7
let student = ["Tom", "Marry", "Waston", "Tom"];

let res = student.entries();
console.log(res)[
// output:
(0, "Tom")
][(1, "Marry")][(2, "Waston")][(3, "Tom")];

from

可以將類陣列轉換成陣列 Ex(map),這邊引用了 MDN 的說明

1
from(arrayLike, mapFn, this);
  • 類陣列(array-like)物件(物件具有 length 屬性以及索引化(indexed)的元素)或
  • mapFn(非必填) 可以傳入 map function 來做進一步的處理
  • this(非必填) mapFn 函式執行時的 this 對象。
1
2
Array.from("Hello");
//output: ['H','e','l','l','o']

假如今天我想要建立一個數字 1–99 的陣列可以怎麼做?一個一個慢慢寫當然是可以,只是寫完可能就天黑了,使用 Array from 搭配 map 一行輕鬆搞定

1
Array.from({ length: 99 }, (v, i) => i + 1);

copyWithin

1
copyWithin(target, start, end);
  • target ( 必填 ):先指定好要塞的位置
  • start: ( 非必填,預設 0 )然後決定要塞進的對象(從哪裡開始複製
  • end:( 非必填,預設等於陣列長度 )複製到哪個元素的前一個位置為止
1
2
3
4
5
6
7
8
9
let student = ["Tom", "Marry", "Waston", "Tom"];

let res = student.copyWithin(0, 2, 3);
console.log(res);
//output: ['Waston', 'Marry', 'Waston', 'Petter']

let result = student.copyWithin(-2, 1);
console.log(result);
//output: ['Waston', 'Marry', 'Marry', 'Waston']

flat

函數以遞迴方式將特定深度的子陣列重新串接成為一新的陣列,會傳入參數來指定巢狀陣列展開的深度 沒有傳的話預設是 1。這邊引用了 MDN 的說明

1
2
3
4
5
6
7
8
9
10
11
let arr1 = [1, 2, [3, 4]];
arr1.flat();
//output: [1, 2, 3, 4]

let arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
//output: [1, 2, 3, 4, [5, 6]]

let arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
//output: [1, 2, 3, 4, 5, 6]

of

將傳入的參數 彙整成陣列

1
2
3
4
5
Array.of("kappa");
//output: ['kappa']

Array.of(1, 2, 3);
// output: [1, 2, 3]

這次在整理的過程中,意外發現有這麼多方法可以用,當然有些是比較新的語法,還是要注意舊款瀏覽器是否支援的問題,不過有了這些方法,真的方便不少啊~