[JS] 陣列方法筆記起來

前言

學習Javascript到應用時,最常使用的就是陣列方法來處理資料,因此多知道一個方法但不需要死背用法來的更重要。這篇也會持續更新學到的方法。

另外整理這篇的契機是在學習過程中,看了偷米騎巴哥的影片和整理圖,十分喜歡,也讓觀念更加清晰。

出處連結在此

另外也很喜歡OxxoStudio這個整理過後的大全分類,借鑒了OxxoStudio的分類整理以自己理解的觀念。

還有其他實用的方法

陣列方法小筆記

1. 會改變原本陣列的內容

> 陣列增減,複製取代

push() :加入到最後 — unshift() :加入到最前

pop() :把最後一個去除 — shift() :把最前一個去除

splice()

splice()中包含三個參數:
參數1(必填):從第幾個開始刪除或新增
參數2(選填):要刪掉幾個,0或負值則不刪除,不填時 參數1 後所有項目都刪除。
參數3(選填):新增的項目,可以是好幾個值

1
2
3
let ary = [1, 2, 3, 4, 5];
ary.splice(1, 0, 1000, 2000, 3000);
console.log(ary); //[1, 1000, 2000, 3000, 2, 3, 4, 5]

copyWithin()

有點像是複製貼上取代的概念,貼上會取代掉原本位置的元素
參數1(必填):從第幾個開始貼上取代
參數2(選填 預設0):從第幾個開始複製
參數3(選填 預設陣列長度):複製到第幾個前(不包含這一個)

1
2
3
4
5
6
7
let ary = [1, 2, 3, 4, 5];

ary.copyWithin(1);
console.log(ary); //[1, 1, 2, 3, 4] 5 超過陣列長度,所以不會出現

ary.copyWithin(2, 1, 3);
console.log(ary); //[1, 2, 2, 3, 5] 複製2,3 從索引2也就是3的位置開始取代

fill()

把陣列中所有元素,換成指定的值
參數1(必填):指定的值
參數2(選填 預設0 全部置換):從第幾個開始換
參數3(選填 預設陣列長度):換到第幾個前(不包含這一個)

1
2
3
4
5
6
7
let ary = [1, 2, 3, 4, 5];

ary.fill('cool', 1);
console.log(ary); // [1, 'cool', 'cool', 'cool', 'cool']

ary.fill('cool', 1, 3);
console.log(ary); // [1, 'cool', 'cool', 4, 5]

> 陣列排序

reverse() :反轉陣列排序

sort()

會將元素轉換成 字串 來排序,預設排序為unicode 從 a 排到 z , 從 小 排到 大,若有十位數以上數字則會產生排序問題,因此需要用以下方法來解決。

1
2
3
4
5
6
7
8
9
10
11
12
13
let ary = [100, 1, 4, 50];

ary.sort((a,b) => b - a);
console.log(ary); // [100, 50, 4, 1] 倒序

ary.sort((a,b) => a - b);
console.log(ary); // [1, 4, 50, 100] 正序

ary.sort((a,b) => a > b ? -1 : 1);
console.log(ary); // [100, 50, 4, 1] 倒序

ary.sort((a,b) => a > b ? 1 : -1);
console.log(ary); // [1, 4, 50, 100] 正序

2. 回傳陣列元素資訊或索引值

(取得陣列而不會改變原始陣列)

> 回傳陣列元素資訊

.length : 回傳陣列的長度(元素的數量)

> 回傳陣列索引值

indexOf()

由左到右判斷是否有 參數1 的值,如果有回傳這個值的索引值,如果沒有回傳 -1
參數1(必填):要判斷的值
參數2(選填 預設0):從第幾個開始判斷

lastIndexOf()

由右到左判斷是否有 參數1 的值,如果有回傳這個值的索引值,如果沒有回傳 -1
參數1(必填):要判斷的值
參數2(選填 預設為最後一個):從第幾個開始判斷

1
2
3
4
5
6
7
8
let ary = [1, 2, 3, 4, 5];
console.log(ary.indexOf(3)); // 2
console.log(ary.indexOf(6)); // -1
console.log(ary.indexOf(2, 3)); // -1

console.log(ary.lastIndexOf(5)); // 4
console.log(ary.lastIndexOf(2, 3)); // 1
console.log(ary.lastIndexOf(5, 3)); // -1

findIndex()

會將陣列中的 每一個 元素帶入函式判斷,並會回傳 第一個 符合判斷條件元素的索引值,如果沒有元素符合則會回傳 -1

> 回傳陣列元素值

find()

會將陣列中的 每一個 元素帶入函式判斷,並會回傳 第一個 符合判斷條件的元素,如果沒有元素符合則會回傳 undefined

1
2
3
4
5
6
7
let ary = [1, 2, 3, 4, 5];
console.log(ary.findIndex(num => num > 2)); // 2(索引值)
console.log(ary.findIndex(num => num < 0)); // -1

console.log(ary.find(num => num > 2)); // 3
console.log(ary.find(num => num < 0)); // undefined

> 回傳一個新字串

join()

可帶入值取代原有陣列的逗號區隔,回傳成字串,未帶入則用逗號隔開

1
2
3
4
5
6
let aryA = [1, 2, 3, 4, 5];
let b = aryA.join('@');
console.log(b); // '1@2@3@4@5' 字串

let b = aryA.join('');
console.log(b); // '12345'

toString()

可以把整個陣列轉換成字串

1
2
3
let ary = [1, 2, 3, 4, 5];
let b = ary.toString();
console.log(b); // 1,2,3,4,5 字串

> 回傳一個新數值

reduce()

將陣列中每一個元素進行計算,結果再與下個元素計算,回傳計算結果。較常見於計算加總。
裡頭有一個函式 (必填) 和 一個初始計算數值 (選填)
函式中可帶入4個參數
參數1(必填):計算的值
參數2(必填):該元素的值
參數3(選填):元素的索引值
參數4(選填):原本的陣列

1
2
3
4
5
6
let aryA = [1, 2, 3, 4, 5];
let b = aryA.reduce((total, num) => total + num);
console.log(b); //  15 = 1+2+3+4+5

let b = aryA.reduce(((total, num) => total + num), 10);
console.log(b); //  25 = 1+2+3+4+5+10

reduceRight()

和reduce類似,差別在計算方式是由右到左,加法不影響,減法則會有差別

1
2
3
4
5
6
let aryA = [1, 2, 3, 4, 5];
let b = aryA.reduce((total, num) => total - num);
console.log(b); //  -13 = 1-2-3-4-5

let b = aryA.reduceRight(((total, num) => total - num));
console.log(b); //  -5 = 5-4-3-2-1

> 回傳一個新陣列

filter()

會將陣列中的 每一個 元素帶入指定的函式內做判斷,並會回傳符合判斷條件的元素組成一個新陣列

1
2
3
let aryA = [1, 2, 3, 4, 5];
let aryB = aryA.filter(num => num % 2 == 1);
console.log(aryB); // [1, 3, 5] 餘1為奇數

slice()

與字串.slice()用法差不多,擷取某段回傳出新陣列
參數1(必填):從第幾個開始擷取
參數2(選填 預設為最後一個):擷取到第幾個前(不包含這一個)

1
2
3
4
5
6
let aryA = [1, 2, 3, 4, 5];
let aryB = aryA.slice(1);
console.log(aryB); // [2, 3, 4, 5]

let aryB = aryA.slice(1, 3);
console.log(aryB); // [2, 3]

concat() :將兩個陣列串接為一個陣列

ES6語法 擴展運算符… 有相同功能

1
2
3
4
5
6
7
let aryA = [1, 2, 3, 4, 5];
let aryB = ['a', 'b', 'c'];
let aryC = aryA.concat(aryB); //陣列A後串接B
console.log(aryC); //  [1, 2, 3, 4, 5, "a", "b", "c"]

let aryC = [...aryA, ...aryB] //使用...
console.log(aryC); //  [1, 2, 3, 4, 5, "a", "b", "c"]
展開運算符(spread operator)

…運用在陣列與物件

1
2
3
4
5
6
let aryA = [1,2,3];
let aryB = [0, ...aryA, 4]; // [0,1,2,3,4]

let objA = { a: 1, b: 2 };
let objB = { ...objA, c: 3 }; // { a:1, b:2, c:3 }
let objC= { ...objA, a: 3 }; // { a:3, b:2 }
剩餘操作符(rest operator)

是解構的一種,意思就是把剩餘的東西放到一個array裏面賦值給它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let aryA = [1,2,3];
let [aryB, ...aryC] = aryA;
console.log(aryB); // 1
console.log(aryC); // [2,3] 如果陣列長度不夠解構 aryC為空陣列[]

let ary = [1,2];
let [a, ...[b,c]] = ary;
console.log(a, b, c); //1 2 undefined

//函式帶入的情況
function test(a, ...rest){
console.log(a); // 1
console.log(rest); // [2,3]
}
test(1,2,3);

//物件用法

let obj = { name: 'Peter', age: 30, city: 'Taipei'};
const {name, ...rest} = obj;
console.log(name); // 'Peter'
console.log(rest); // {age: 30, city: 'Taipei'}

Array.of()

可以把數字、字串轉換成陣列

1
2
let ary = Array.of(1, 2, 3, 'a', ['b']);
console.log(ary); // [1, 2, 3, "a", ["b"]]

Array.from()

可將(「類陣列物件」:具有length屬性和索引值) 或是(「可迭代的物件」:可利用迭代的方式取得本身的元素eg: Map和Set等) 轉換成陣列,有兩個參數
參數1(必填):「類陣列物件」或是「可迭代的物件」
參數2(選填):改變轉換陣列的函式

1
2
3
4
5
6
7
let a = '12345';
let b = Array.from(a);
console.log(b); // ["1", "2", "3", "4", "5"]

let b = Array.from(a, item => 0 + item );
console.log(b); // ["01", "02", "03", "04", "05"]

「類陣列物件」:需具有length屬性和索引值

1
2
3
4
5
6
7
8
9
10
let obj = {
'0': 1,
'2': 3,
'1': 2,
'4': 5,
'3': 4,
length: 5
};
let ary = Array.from(obj);
console.log(ary); // [1, 2, 3, 4, 5]

flat()

可以把多層陣列平面化,一個參數(選填 預設1)為平面化幾層,設定Infinity可以直接全面平面化,回傳成新陣列

1
2
3
4
5
6
7
let aryA = [1, 2, [[3]], [[[4], 5]]];
let aryB = aryA.flat();
let aryC = aryA.flat(2);
let aryD = aryA.flat(Infinity);
console.log(aryB); // [1, 2, [3], [[4], 5]]
console.log(aryC); // [1, 2, 3, [4], 5]
console.log(aryD); // [1, 2, 3, 4, 5]

flatMap()

map() + flat() 帶入函式後傳出的值再平面化

1
2
3
let aryA = [1, 2, [[3]], [[[4], 5]]];
let aryB = aryA.flatMap(item => item + 10);
console.log(aryB); // [11, 12, "310", "4,510"]

map()

與 forEach 非常類似,但是 map 會 return 一個值,並會產生一個新陣列
裡頭有一個函式 (必填) 和 一個callback函式裡的 this 參數 (選填)
函式中可帶入3個參數
參數1(必填):每個元素帶入的變數
參數2(選填):該元素的索引值
參數3(選填):原本的陣列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let aryA = [1, 2, 3, 4, 5];
let aryB = aryA.map((item, index) => {
return `${index + 1}:${item > 2}`
});
console.log(aryB); // ["1:false", "2:false", "3:true", "4:true", "5:true"]

aryA.map((item, index, ary) => {
return ary[index] = item * 10;
});
console.log(aryA); // [10, 20, 30, 40, 50] 更改原陣列

// 如果要使用callback函式裡 this 的參數,則「不能使用」箭頭函式,因為箭頭函式的 this 指向和函式的 this 指向不同,所以要用一般的函式處理。

let aryA = [1,2,3,4,5];
let aryB = aryA.map(function(item){
return item + this; // 此處的 this 為 10
}, 10);
console.log(aryB); // [11, 12, 13, 14, 15]

3. 針對每個元素處理,不用return

forEach()

會將陣列中的 每一個 元素帶入指定的函式內做運算,
裡頭有一個函式 (必填) 和 一個callback函式裡的 this 參數 (選填)
函式中可帶入3個參數
參數1(必填):每個元素帶入的變數
參數2(選填):該元素的索引值
參數3(選填):原本的陣列

forEach() 無法用 break 中斷,如果想要中斷執行的話要使用傳統的 for 迴圈。

1
2
3
4
let ary = [1, 2, 3, 4, 5];
let total = 0;
ary.forEach(item => total += item);
console.log(total); // 15

可更改原始陣列

1
2
3
4
5
let ary = [1, 2, 3, 4, 5];
ary.forEach((item, index, ary) => {
ary[index] = item * 10;
});
console.log(ary); // [10,20,30,40,50]

4. 判斷並回傳布林值

Array.isArray()

判斷一個物件是否為陣列,如果是就回傳 true,不然就回傳 false。

1
2
3
4
5
let ary = [1, 2, 3, 4, 5];
let obj = {a:1, b:2, c:3};

console.log(Array.isArray(ary)); // true
console.log(Array.isArray(obj)); // false

every()

會將陣列中的 每一個 元素帶入指定的函式內做判斷,
全部符合條件回傳 true,其中一個元素條件不符合,便回傳false。

1
2
3
let ary = [1, 2, 3, 4, 5];
console.log(ary.every(item => item > 4)); // false
console.log(ary.every(item => item > 0)); // true

some()

會將陣列中的 每一個 元素帶入指定的函式內做判斷,
其中一個元素符合條件回傳 true,全部不符合,便回傳false。

1
2
3
let ary = [1, 2, 3, 4, 5];
console.log(ary.some(item => item > 4)); // true
console.log(ary.some(item => item < 0)); // false

includes()

判斷陣列中是否包含某個值,如果有包含就回傳 true,不然就回傳 false
參數1(必填):要判斷的值
參數2(選填):從第幾個開始判斷

1
2
3
let ary = [1, 2, 3, 4, 5];
console.log(ary.includes(2)); // true
console.log(ary.includes(2,3)); // false

5. 其他

> 回傳陣列值

valueOf()

回傳原本陣列的值,但如果原本陣列有修改,那麼回傳後的陣列值也會跟著改變,類似傳參考的概念。

1
2
3
4
5
let aryA = [1, 2, 3, 4, 5];
let aryB = aryA.valueOf();
aryB[0] = 'a';
console.log(aryA); // ["a", 2, 3, 4, 5]
console.log(aryB); // ["a", 2, 3, 4, 5]

> 回傳一個的Array Iterator物件

keys()

回傳陣列中的每一個索引值 key 成為一個新的 Array Iterator 陣列迭代器物件
因為是 Array Iterator 物件,可以透過 Array.from, for…of來取得。

1
2
3
4
5
6
7
8
9
10
11
12
13
let a = ['a','b','c','d','e'];
let b = a.keys(); // Array Iterator
let c = Array.from(b);
console.log(c); // [0, 1, 2, 3, 4]


let a = ['a','b','c','d','e'];
let b = a.keys();
let d = [];
for (let key of b) {
d.push(key);
}
console.log(d); // [0, 1, 2, 3, 4]

延伸閱讀 for…of

values()

回傳陣列中的每一個元素值 成為一個新的 Array Iterator 陣列迭代器物件

1
2
3
4
5
let a = ['a','b','c','d','e'];
let b = a.values(); // Array Iterator
for (let value of b) {
console.log(value);
} //依序出現 a b c d e

entries()

回傳陣列中的每一個索引值 key 與對應元素 成為一個新的 Array Iterator 陣列迭代器物件

fromEntries()

可把Array Iterator 陣列迭代器物件轉成物件Object

1
2
3
4
5
6
7
8
9
10
11
12
13
let a = ['a','b','c','d','e'];
let b = a.entries(); // Array Iterator

let c = [];
for (let [key, value] of b) {
c.push(`${key}${value}`);
}
console.log(c); // ["0a", "1b", "2c", "3d", "4e"]

let a = ['a','b','c','d','e'];
let b = a.entries();
const e = Object.fromEntries(b);
console.log(e); // {0: "a", 1: "b", 2: "c", 3: "d", 4: "e"}
Author

KaiYun Cheng

Posted on

2020-11-03

Updated on

2024-04-13

Licensed under

Comments

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×