JS-各種迴圈的用法

紀錄各種迴圈的用法。

前言

JS常常需要針對 陣列(Array)物件(Object) 這二種資料進行分析及修改,
故整理下列幾種方法,

  • 單純遍歷陣列元素

    • for
    • forin
    • forEach
  • 判斷是否符合資格

    • every:遍歷每個元素判斷是否皆符合條件,若其一不符,就回傳 false
    • some: 遍歷每個元素判斷是否皆符合條件,若其一符合,就回傳 true
  • 產生新的陣列

    • map:遍歷每個元素,進行 加工、校正
    • filter:遍歷每個元素,保留符合條件(true)的值,不符合,則去除掉。
    • reduce:遍歷每個元素,依序組合、加總,然後丟給下個元素,最終會回傳一個結果。

for

最常見的用法,不多加說明。

範例

1
2
3
4
5
let arr = ["Kanboo", "Jack", "Rabbit", "Lucas", "Jack", "Lucas", "Rabbit"];

for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}

forin

可傳入 objecarray 型態的資料。

範例

Array型態
1
2
3
4
5
var arr = ["zero","one","two"];

for (var key in arr) {
console.log(arr[key]);
}
Object型態
1
2
3
4
5
var obj = {a: 1, b: 2, c: 3};

for (const item in obj) {
console.log(obj[item]);
}

forEach

可用來取代 for 的寫法,讓程式碼更簡短,省略掉定義 iarr.length…等動作。

語法

1
2
3
arr.forEach( callback(currentValue, index, array){
/* your code */
});

callback

  • currentValue(常用):原陣列目前所迭代處理中的元素。
  • index(選用):原陣列目前處理中的元素之索引
  • array(選用):呼叫 forEach() 方法的陣列。

範例

ES5
1
2
3
4
5
const arr = ['a', 'b', 'c'];

arr.forEach(function(element) {
console.log(element);
});
ES6
1
2
3
4
5
const arr = ['a', 'b', 'c'];

arr.forEach((element) => {
console.log(element);
});

every

對每個陣列元素判斷是否皆符合條件,若其一不符,就回傳 false

語法

1
2
3
arr.every( callback(currentValue, index, array){
/* your code */
});

callback

  • currentValue(常用):原陣列目前所迭代處理中的元素。
  • index(選用):原陣列目前處理中的元素之索引
  • array(選用):呼叫 every() 方法的陣列。

範例

1
2
3
4
5
6
7
8
9
10
function isBigEnough(element, index, array) {
//是否大於10
return element >= 10;
}

// 其中 5 沒有大於 10
[12, 5, 8, 130, 44].every(isBigEnough); // false

// 皆符合大於 10
[12, 54, 18, 130, 44].every(isBigEnough); // true

some

對每個陣列元素判斷是否皆符合條件,若其一符合,就回傳 true

語法

1
2
3
arr.some( callback(currentValue, index, array){
/* your code */
});

callback

  • currentValue(常用):原陣列目前所迭代處理中的元素。
  • index(選用):原陣列目前處理中的元素之索引
  • array(選用):呼叫 some() 方法的陣列。

範例

1
2
3
4
5
6
7
8
9
10
function isBiggerThan10(element, index, array) {
//是否大於10
return element > 10;
}

// 全部都無 大於10
[2, 5, 8, 1, 4].some(isBiggerThan10); // false

// 其中 12 有大於10
[12, 5, 8, 1, 4].some(isBiggerThan10); // true

map

可對每個陣列元素進行 加工、校正 的處理,最後回傳一個 新的陣列

原先的陣列與後來新產生出的陣列,個數(Array.length) 會一樣多。

語法

1
2
3
arr.map( callback(currentValue, index, array){
/* your code */
});

callback

  • currentValue(常用):原陣列目前所迭代處理中的元素。
  • index(選用):原陣列目前處理中的元素之索引
  • array(選用):呼叫 map() 方法的陣列。

範例1

加工
1
2
3
4
5
6
7
8
var myArr = [ 1, 2, 3 ];

var newArr = myArr.map(function(element) {
// 每個數都加1
return element + 1;
});

console.log(newArr); // [ 2, 3, 4 ]

範例2

校正
1
2
3
4
5
6
7
8
9
10
11
12
var myArr = [ 1, 20, 3, 40, 50, 6, 7, 80, 9, 10 ];

var newArr = myArr.map(function(element) {
// 校正大於10的數字,統一變100
if (element < 10){
return element;
}else{
return 100;
}
});

console.log(newArr); // [1, 100, 3, 100, 100, 6, 7, 100, 9, 100]

filter

遍歷每個元素,保留符合條件(true)的值,不符合,則去除掉。

原先的陣列與後來新產生出的陣列,個數(Array.length)可能不一樣多。

語法

1
2
3
arr.filter( callback(currentValue, index, array){
/* your code */
});

callback

  • currentValue(常用):原陣列目前所迭代處理中的元素。
  • index(選用):原陣列目前處理中的元素之索引
  • array(選用):呼叫 filter() 方法的陣列。

範例

1
2
3
4
5
6
7
8
var myArr = [ 1, 20, 3, 40, 50, 6, 7, 80, 9, 10 ];

var newArr = myArr.filter(function(element) {
// 取得大於50的數
return element >= 50;
});

console.log(newArr); // [50, 80]

reduce

遍歷每個元素,依序組合、加總,然後丟給下個元素,最終會回傳一個結果。

語法

1
2
3
arr.reduce( callback(accumlator, currentValue, index, array){
/* your code */
}, initialValue)

callback

  • accumulator(常用):用來累積回呼函式回傳值的累加器。
  • currentValue(常用):原陣列目前所迭代處理中的元素。
  • index(選用):原陣列目前所迭代處理中的元素之索引
  • array(選用):呼叫 reduce() 方法的陣列。

initialValue(常用):於第一次呼叫 callback 時要傳入的累加器初始值。

範例1

注意reduce第二個參數 0 , 代表的意思是開始執行遍歷前的初始值

有設定初始值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var myArr = [ 1, 2, 3 ];

// 處理每個元素後等待回傳結果,第一次處理時代入初始值 0
var result = myArr.reduce(function(prev, element) {
console.log(prev,element);

// 與之前的數值加總,回傳後代入下一輪的處理
return prev + element;
}, 0);

/*
prev,element 的執行log,共執行三次
第一次:0 1
第二次:1 2
第三次:3 3
*/


// 最終結果
console.log(result); // 6

範例2

注意此次沒有設定reduce第二個參數, 此時就會自動抓取陣列第一個元素當作初始值。

無初始值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var myArr = [ 1, 2, 3 ];

// 處理每個元素後等待回傳結果,第一次處理時代入初始值 0
var result = myArr.reduce(function(prev, element) {
console.log(prev,element);

// 與之前的數值加總,回傳後代入下一輪的處理
return prev + element;
});

/*
prev,element 的執行log,共執行二次
第一次:1 2
第二次:3 3
*/


// 最終結果
console.log(result); // 6

範例3

除了一般數字的加總,也可配合判斷式,最終產出一個新的陣列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let source = ["Kanboo", "Jack", "Rabbit", "Lucas", "Jack", "Lucas", "Rabbit"];
let result_04 = source.reduce((p, c) => {
//includes 判斷是否已存在
if (!p.includes(c)) p.push(c);
console.log("p", p);
return p;
}, []);


/*
迴圈的執行log,共執行七次

p ["Kanboo"]
p ["Kanboo", "Jack"]
p ["Kanboo", "Jack", "Rabbit"]
p ["Kanboo", "Jack", "Rabbit", "Lucas"]
p ["Kanboo", "Jack", "Rabbit", "Lucas"]
p ["Kanboo", "Jack", "Rabbit", "Lucas"]
p ["Kanboo", "Jack", "Rabbit", "Lucas"]
*/

//最終結果
console.log("result_04", result_04); // ["Kanboo", "Jack", "Rabbit", "Lucas"]