前言
學習常用的陣列的處理方式
本篇文章分別針對以下幾個方法來介紹:
(直接點下方連結就能跳到指定區域)
修改原始陣列的方法 (本類別的方法可以變更原始陣列)
copyWithin()、fill()、pop()、push()、shift()、unshift()、sort()、splice()
取得陣列而不會更動原始陣列的方法
對陣列內每個元素進行同樣處理的方法(疊代)
修改原始陣列的方法
copyWithin()
複製陣列中的元素,並置換原始陣列中原本的元素。
參數(有三個)
- 第一個是要置換的位置(必填)。
- 第二個是複製起點的索引值(選填)。
- 第三個是複製終點的索引值 + 1(選填)。
如果省略第二個參數,則會從陣列第一個元素開始複製。
如果省略第三個參數,則會複製到陣列最後一個元素為止。
使用此方法處理後的陣列長度必須等於原本的長度,
如果超過原本長度,則超過的部分不予顯示。
範例
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
// 從 Dinah 開始置換,從 Bonnie 開始複製到 Chloe
peoples.copyWithin(3,1,3);
console.log(peoples);
// ['Adela', 'Bonnie', 'Chloe', 'Bonnie', 'Chloe'];
// ['Bonnie', 'Chloe'] 取代了 ['Dinah', 'Emma']
fill()
用一個指定的值置換陣列中所有元素。
參數(有三個)
- 第一個是指定要置換的值(必填)。
- 第二個是置換起點的索引值(選填,預設為 0,即置換全部)。
- 第三個是置換終點的索引值 + 1(選填,預設等於陣列長度)。
範例
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
// 索引值 2 跟 3 的值置換為「Uriah」
console.log(peoples.fill('Uriah', 2, 4));
// ['Adela', 'Bonnie', 'Uriah', 'Uriah', 'Emma'];
// 從索引值 1 開始的值置換為「Tyrone」
console.log(peoples.fill('Tyrone', 1));
// ['Adela', 'Tyrone', 'Tyrone', 'Tyrone', 'Tyrone'];
pop()
從陣列中刪除最後一個元素並回傳該元素。
範例
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
// 刪除並回傳最後面的元素
console.log(peoples.pop());
// 'Emma'
// 檢查原陣列
console.log(peoples);
// ['Adela', 'Bonnie', 'Chloe', 'Dinah']
提醒:跟下面的 shift() 剛好相反,可以一起記。
shift()
從陣列中刪除第一個元素並回傳該元素。
範例
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
console.log(peoples.shift());
// 'Adela'
console.log(peoples);
// ['Bonnie', 'Chloe', 'Dinah', 'Emma'];
提醒:跟上面的 pop() 剛好相反,可以一起記。
push()
在陣列尾端加入一個或數個元素,並回傳修改後的陣列。
範例
var peoples = ['Adela', 'Bonnie'];
// 增加一個資料
peoples.push('Todd');
console.log(peoples);
// ['Adela', 'Bonnie','Todd'];
// 繼續增加數個資料
peoples.push('Chloe', 'Dinah');
console.log(peoples);
// ['Adela', 'Bonnie', 'Todd', 'Chloe', 'Dinah'];
提醒:跟下面的 unshift() 剛好相反,可以一起記。
unshift()
在陣列前端加入指定的一個或數個元素,並回傳修改後的陣列及新長度。
範例
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
// 增加一個資料
console.log(peoples.unshift('Stan'));
console.log(peoples);
// 6
// ['Stan', 'Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma']
提醒:跟上面的 push() 剛好相反,可以一起記。
sort()
對陣列的元素進行排序並回傳陣列。
參數
此方法需要指定一個函式作為參數來定義陣列內的排序,且函式包含兩個參數,以 a 跟 b 為例,若 a - b < 0,則 a 會排在 b 前面;若 a - b > 0,則 a 會排在 b 的後面;若 a - b = 0,則 a 跟 b 兩者的排序不會變動,但會跟全部的元素一起比較來排序。假如省略函式參數,陣列會將各個元素轉為字串,並根據每一個字元的 Unicode 進行排序。
範例
// 指定函式參數的例子 1
let nums = [99, 999, 88, 888, 666];
nums.sort(function(a, b) {
return a - b; // 由小到大排列
});
console.log(nums);
// [88, 99, 666, 888, 999]
// 指定函式參數的例子 2
let nums = [99, 999, 88, 888, 666];
nums.sort(function(a, b) {
return b - a; // 由大到小排列
});
console.log(nums);
// [999, 888, 666, 99, 88]
// 沒指定函式參數的例子
let nums = [99, 999, 88, 888, 666];
nums.sort();
console.log(nums);
// [666, 88, 888, 99, 999]
splice()
移除或取代陣列中的元素。
參數(有三個)
- 第一個是要改動的元素索引值(必填)。
- 第二個是要移除的總筆數(選填),若省略,則從刪除起點開始的所有元素都會被刪除;若設定為 0 或負數,則不會有元素被移除。
- 第三個是要添加的內容(選填),若省略,則原陣列資料不會被新資料替換,也就是單純刪除陣列資料的意思。
範例
// 從'Chloe'開始,刪除一筆資料
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
peoples.splice(2,1);
console.log(peoples);
// ['Adela', 'Bonnie', 'Dinah', 'Emma']
// 指定第三個參數,取代原本的資料
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
// 從'Chloe'開始,替換一筆資料為'Sid'
peoples.splice(2,1,'Sid');
console.log(peoples);
// ['Adela', 'Bonnie', 'Sid', 'Dinah', 'Emma']
提醒:小心不要跟 slice() 搞混囉~
取得陣列的方法
本類別的方法不會修改到原始陣列,而是以某些表現形式回傳值或新陣列。
slice()
用索引值選取起點到終點,就可以複製該範圍(不含終點)的元素並回傳一個新陣列。
參數(有兩個)
- 第一個是起點索引值。
- 第二個是終點索引值 + 1。
值得一提的是,兩個參數均非必填,如果忽略的話,將會複製整個原始陣列。
範例
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
// 兩個參數均填入
let peopleleave = peoples.slice(3,5);
console.log(peopleleave);
// ['Dinah', 'Emma']
// 忽略兩個參數
let samepeoples = peoples.slice();
console.log(samepeoples);
// ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
提醒:小心不要跟 splice() 搞混囉~
concat()
用來合併數個陣列,會回傳一個合併後的新陣列,且不會更改到原始的陣列。
範例
var peoples1 = ['Adela', 'Bonnie', 'Chloe'];
var peoples2 = ['Dinah', 'Emma'];
var peoples3 = peoples1.concat(peoples2);
console.log(peoples3);
// ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma']
// 兩個原陣列不變
console.log(peoples1); // ['Adela', 'Bonnie', 'Chloe']
console.log(peoples2); // ['Dinah', 'Emma']
indexOf()
在陣列中搜尋指定元素,將會回傳第一個符合條件的元素的索引值;
若在陣列中沒找到,則回傳 -1。
參數(有兩個)
- 第一個參數為要判斷的值(必填)。
- 第二個參數為搜尋起點的索引值(選填,預設為 0)。
範例
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
console.log(peoples.indexOf('Bonnie'));
// 1,代表元素在索引值 1
console.log(peoples.indexOf('Chloe'));
// 2,只會回傳第一個符合的元素索引值
console.log(peoples.indexOf('Scott'));
// -1,陣列中無此資料
console.log(peoples.indexOf('Bonnie',3));
// -1,從索引值 3 開始找,沒找到
toString()
將陣列以字串方式回傳。
範例
var peoples = ['Adela', 'Bonnie', 'Chloe', 'Dinah', 'Emma'];
console.log(peoples.toString());
// 'Adela, Bonnie, Chloe, Dinah, Emma'
陣列疊代的方法
什麼是疊代?
疊代指的是對物件重複同樣的處理方法,每重複一次就稱為一次疊代。JavaScript 中的疊代大部分指的是迴圈,但陣列中也有類似迴圈功能的方法,這些方法會產生「疊代器」來達成類似迴圈的效果。
帶有函式參數的陣列方法
有些方法在處理陣列時,會使用回呼函式作為參數。這些方法會採樣原始陣列的長度,而在回呼中被加入的元素則不會被巡訪。所以如果你需要更改陣列,還是應該先複製一個新陣列來操作。
回傳疊代器物件的陣列方法
有些方法回傳的不是新陣列或是特定的值,而是一個陣列疊代器物件,而要操作或讀取該物件的值就需要使用 for…of 語法。for…of 的用法是這樣的:
for ( let 要疊代的元素 of 疊代器){
要對元素做的事;
}
[筆記] JavaScript ES6 中的 for … of(處理陣列的好幫手)
every()
如果此陣列中的 每個元素 都滿足回呼函式給的條件,則回傳 true,如果有任何一個不符合條件,則回傳 false。
參數
- 含有一個參數,此參數為 callback 函式。
- 函式中有一個必填的參數,這個參數用來代表陣列中每個需要被疊代的元素。
- 函式中的 return 後面接著的是要判斷的條件。
範例
var array = [
{
name: 'Adela',
age: 18
},
{
name: 'Bonnie',
age: 24
},
{
name: 'Chloe',
age: 1
},
{
name: 'Dinah',
age: 3
}
];
var ans = array.every(function(item, index, array){
console.log(item, index, array); // 物件, 索引, 全部陣列
return item.age > 10 // 當全部 age 大於 10 才能回傳 true
});
console.log(ans); // false: 只要有部分不符合,則為 false
var ans2 = array.every(function(item, index, array){
return item.age < 25
});
console.log(ans2); // true: 全部 age 都小於 25
some()
陣列中 至少有一個元素滿足 回呼函式的條件,就會返回 true,如果全部元素都不符合條件,則回傳 false。
參數
- 含有一個參數,此參數為 callback 函式。
- 函式中有一個必填參數及三個選填參數:
每個被疊代的元素(必填)。
目前處理的元素索引值(選填)。
使用該方法的陣列(選填)。
執行此函式的 this 值(選填)。
範例
var array = [
{
name: 'Adela',
age: 18
},
{
name: 'Bonnie',
age: 24
},
{
name: 'Chloe',
age: 1
},
{
name: 'Dinah',
age: 3
}
];
var ans = people.some(function(item, index, array){
return item.age > 10 // 當全部 age 大於 10 才能回傳 true
});
console.log(ans); // true: 只要有部分符合,則為 true
var ans2 = people.some(function(item, index, array){
return item.age < 25
});
console.log(ans2); // true: 只要有部分符合,則為 true
var ans2 = people.some(function(item, index, array){
return item.age > 25
});
console.log(ans2); // false: 全部都不符合則為 false
filter()
使用此方法給定條件,就能將符合條件的元素從陣列中過濾出來,過濾出來的元素會以一個陣列的形式回傳。
參數
- 含有一個參數,此參數為 callback 函式。
- 函式中有一個必填參數及三個選填參數:
每個被疊代的元素(必填)。
目前處理的元素索引值(選填)。
使用該方法的陣列(選填)。
執行此函式的 this 值(選填)。 - 函式中的 return 後面接著的是要判斷的條件。
範例
var array = [
{
name: 'Adela',
like: '蛋糕',
age: 18
},
{
name: 'Bonnie',
like: '泡麵',
age: 24
},
{
name: 'Chloe',
like: '果汁',
age: 1
},
{
name: 'Dinah',
like: '米餅',
age: 3
}
];
var filterEmpty = people.filter(function(item, index, array){
});
console.log(filterEmpty); // 沒有條件,會是一個空陣列
var filterAgeThan5 = people.filter(function(item, index, array){
return item.age > 5; // 取得大於五歲的
});
console.log(filterAgeThan5); // Adela, Bonnie 這兩個物件
var filterDouble = people.filter(function(item, index, array){
return index % 2 === 1; // 取得陣列中雙數的物件
});
console.log(filterDouble); // Bonnie, Dinah 這兩個物件
find()
find() 與 filter() 很像,但 find() 只會回傳一次值,且是第一次為 true 的值,如果找不到則回傳 undefined。
參數
- 含有一個參數,此參數為 callback 函式。
- 函式中有一個必填參數及三個選填參數:
每個被疊代的元素(必填)。
目前處理的元素索引值(選填)。
使用該方法的陣列(選填)。
執行此函式的 this 值(選填)。 - 函式中的 return 後面接著的是要判斷的條件。
範例
var array = [
{
name: 'Adela',
like: '蛋糕',
age: 18
},
{
name: 'Bonnie',
like: '泡麵',
age: 24
},
{
name: 'Chloe',
like: '蘿蔔泥',
age: 1
},
{
name: 'Dinah',
like: '蘿蔔泥',
age: 3
}
];
var findEmpty = people.find(function(item, index, array){
});
console.log(findEmpty);
// 沒有條件,會是 undefined
var findAgeThan5 = people.find(function(item, index, array){
return item.age > 5;
// 取得大於五歲的
});
console.log(findAgeThan5);
// 雖然答案有兩個,但只會回傳 Adela 這一個物件
var findLike = people.find(function(item, index, array){
return item.like === '蘿蔔泥';
// 取得陣列 like === '蘿蔔泥'
});
console.log(findLike);
// 雖然答案有兩個,但只會回傳第一個 Chloe 物件
forEach()
forEach 是這幾個陣列函式最單純的一個,不會額外回傳值,只單純執行每個陣列內的物件或值。
範例
var array = [
{
name: 'Adela',
like: '蛋糕',
age: 18
},
{
name: 'Bonnie',
like: '泡麵',
age: 24
},
{
name: 'Chloe',
like: '蘿蔔泥',
age: 1
},
{
name: 'Dinah',
like: '蘿蔔泥',
age: 3
}
];
var forEachIt = people.forEach(function(item, index, array){
console.log(item, index, array); // 物件, 索引, 全部陣列
return item; // forEach 沒在 return 的,所以這邊寫了也沒用
});
console.log(forEachIt); // undefined
people.forEach(function(item, index, array){
item.age = item.age + 1; // forEach 就如同 for,不過寫法更容易
});
console.log(people); // 全部 age + 1
map()
使用 map() 時他需要回傳一個值,他會透過函式內所回傳的值組合成一個陣列。
- 如果不回傳則是 undefined
- 回傳數量等於原始陣列的長度
範例
var array = [
{
name: 'Adela',
like: '蛋糕',
age: 18
},
{
name: 'Bonnie',
like: '泡麵',
age: 24
},
{
name: 'Chloe',
like: '蘿蔔泥',
age: 1
},
{
name: 'Dinah',
like: '蘿蔔泥',
age: 3
}
];
var mapEmpty = people.map(function(item, index, array){
});
console.log(mapEmpty);
// [undefined, undefined, undefined, undefined]
var mapAgeThan5 = people.map(function(item, index, array){
return item.age > 5;
// 比較大於五歲的
});
console.log(mapAgeThan5);
// [true, true, false, false]
var mapAgeThan5_2 = people.map(function(item, index, array){
// 錯誤示範
if (item.age > 5) {
return item;
// 回傳大於五歲的
}
return false;
// 別以為空的或是 false 就不會回傳
});
console.log(mapAgeThan5_2);
// [{name: 'Adela'...}, {name: 'Bonnie'...}, false, false]
var mapEat = people.map(function(item, index, array){
if (item.like !== '蘿蔔泥') {
return `${item.like} 好吃`;
} else {
return `${item.like} 不好吃`;
}
});
console.log(mapEat);
// ["蛋糕 好吃", "泡麵 好吃", "蘿蔔泥 不好吃", "蘿蔔泥 不好吃"]
reduce()
reduce() 和其他幾個差異就很大了,他可以與前一個回傳的值再次作運算,參數包含以下:
- accumulator: 前一個參數,如果是第一個陣列的話,值是以另外傳入或初始化的值
- currentValue: 當前變數
- currentIndex: 當前索引
- array: 全部陣列
範例
var array = [
{
name: 'Adela',
like: '蛋糕',
age: 18
},
{
name: 'Bonnie',
like: '泡麵',
age: 24
},
{
name: 'Chloe',
like: '蘿蔔泥',
age: 1
},
{
name: 'Dinah',
like: '蘿蔔泥',
age: 3
}
];
var reduceEmpty = people.reduce(function(accumulator, currentValue, currentIndex, array){
});
console.log(reduceEmpty); // 沒有條件,會是 undefined
var reducePlus = people.reduce(function(accumulator, currentValue, currentIndex, array){
// 分別為:前一個回傳值, 目前值, 當前索引值
console.log(accumulator, currentValue, currentIndex);
return accumulator + currentValue.age; // 與前一個值相加
}, 0); // 傳入初始化值為 0
console.log(reducePlus); // 總和為 46
var reducePlus = people.reduce(function(accumulator, currentValue, currentIndex, array){
console.log('reduce', accumulator, currentValue, currentIndex)
return Math.max( accumulator, currentValue.age ); // 與前一個值比較哪個大
}, 0);
console.log(reducePlus); // 最大值為 24
reduce() 的使用方法更為豐富,想認識更詳細可參考 MDN
其它
預設的陣列行為內的 this 是指向 window (本篇中除了 reduce() 是傳入初始資料),如果要改,可以在 function 後傳入。
範例
// arr.forEach(function callback(currentValue, index, array) {
// your iterator
// }[, thisArg]);
var ans3 = people.forEach(function(item, index, array){
console.log(this)
// 這邊的 this 就會使用後方傳入的
return item.age < 25
}, people); // 傳入的物件,替代 this,如果無則是 window
參考資料
Cheatsheet for Array Methods - JavaScript 陣列方法大全
JavaScript Array 陣列操作方法大全 ( 含 ES6 )
JavaScript 陣列處理方法 [filter(), find(), forEach(), map(), every(), some(), reduce()]
[JS] JavaScript 疊代與迴圈(iterate and loop
[JS] JavaScript 疊代器(Iterator)