介紹JS array的使用(filter, map, sort, reduce)
Array資料 https://github.com/hoyi-23/JavaScript30/blob/main/JS4-Array%20Cardio/index.html
Array.prototype.filter();
filter()方法會建立一個經指定的函式運算後,由原陣列中通過該函式檢驗之元素所構成的新陣列
const Nums = [1,2,3,4,5,6];
const newNums = Nums.filter(num => num>3);
console.log(newNums);
// [object Array] (3) [4,5,6]
練習一: 取出在西元1500年後出生的投資者
const fifteen = inventors.filter(function(inventor){
if(inventor.year>=1500 && inventor.year <= 1600){
return true; //true的意思就是保留他
};
});
// console.log(fifteen); 使用log會有點難閱讀
console.table(fifteen);
使用arrow function 縮減
const fifteen = inventors.filter(inventor=>inventor.year>=1500 && inventor.year <= 1600);
console.table(fifteen);
Array.prototype.map();
map()以我們想要的方法,轉換陣列內的元素,並放入另一個新的陣列回傳。
const cart = [ {itemName:'noodle',price:150},{itemName:'rice',price:300}]
//轉換陣列,將物品提出
const itemNames = cart.map(item => item.itemName);
console.log(itemNames) // [object Array] (2)
["noodle","rice"]
//將價格打八折後取出
const discounts = cart.map (item => item.price * 0.8);
console.log(discounts); // [object Array] (2)
[120,240]
練習二: 取出每位inventor的first Name 與 Last Name
const NameList = inventors.map(inventor => `${inventor.first} ${inventor.last}`);
console.log(NameList);
補充 : filter()和map()的不同
filter()是過濾作用,傳入10個資料,因過濾條件,最後得出的結果可能少於10個。
map()是重組,將原本的資料以不同的方法重新用成一個新的陣列資料,10筆資料出來後還是10筆。
Array.prototype.sort();
sort()會將陣列的所有元素進行排序,並回傳原本的陣列,排序會改變,預設的排序順序是根據字串的Unicode編碼位置而定,也可以依照我們想要的方式改變
const array = [1,5,8,9,2,4,3,7,2000];
array.sort();
console.log(array); //[1,2,2000,3,4,5,7,8,9]
帶入有條件的匿名函式來當參數,參數必須有兩個,然後再依照這兩個參數比較回傳的值,來當排序依據。
回傳值影響的排序原則 :
- 當回傳值為負數,那麼前面的數放在前面。
- 當回傳值為正數,那麼後面的數在前面。(a,b兩者比較,若回傳正數值,那麼小的值放前面)
- 當回傳值為零,保持不動。
const array = [1,5,8,9,2,4,3,7,2000];
array.sort(function(a,b){
if (a>b) {return 1;}else{return -1;}
}); //這句的意思:a,b兩者比較,若a>b,回傳正數值(true),小的數字放前面,大放後。
console.log(array); //[1,2,3,4,5,7,8,9,2000]
const array = [1,5,8,9,2,4,3,7,2000];
array.sort(function(a,b){return a-b;});
console.log(array); //[1,2,3,4,5,7,8,9,2000]
//a-b>0,回傳值為正數,依升序排列。
練習三: 重新排序陣列,依照最老(出生年最小)到年輕
// const ordered = inventors.sort(function(a, b) {
// if(a.year > b.year) {
// return 1;
// } else {
// return -1;
// }
// });
const ordered = inventors.sort((a, b) => a.year > b.year ? 1 : -1);
console.table(ordered);依照出生年分 最早到最後排序
練習四: 依照每個人的年齡排序(小到大)
const ageOrder = inventors.sort(function(a,b){ if((a.passed-a.year)>(b.passed-b.year)){return 1;}else{return -1;}
});
console.log(ageOrder)
//簡化寫法
const ageOrder = inventors.sort((a,b)=>(a.passed-a.year)>(b.passed-b.year)? 1:-1);
console.log(ageOrder)
練習五: 將people陣列的姓氏(last name)字母首字,依照a-z排列。
const alpha = people.sort((lastOne, nextOne) => {
const [aLast, aFirst] = lastOne.split(', ');
const [bLast, bFirst] = nextOne.split(', ');
return aLast > bLast ? 1 : -1;
});
console.log(alpha);
使用到split()方法,作用是將內容拆分string成array。
Array.prototype.reduce();
reduce() 會對陣列中的每一個元素由左至右作累加的動作,也可以與前一個回傳的值再次作運算,參數包含以下:
//Array.prototype.reduce()語法
Array.reduce(callback,[initialValue])
- accumulator(acc) 前一個參數,如果是第一個陣列的話,值得以另外傳入或initialValue。
- currentValue(cur) 當前變數
- currentIndex(idx) 當前索引(若有初始化值,則索引為0;無則為1)
- array 全部陣列
- initialValue 作為第一次callback函數時的第一個參數值,如果沒有提供初始值,會造成undefined
沒有回傳的條件,會是 undefined
const NumArray = [1,2,3,4,5];
const reduceEmpty = NumArray.reduce(function(accumulator, currentValue, currentIndex, array){
});
console.log(reduceEmpty); // 沒有回傳的條件,會是 undefined
一般用法 總合相加值
round 1 - 0 1 0
round 2 - 1 2 1
round 3 - 3 3 2
round 4 - 6 4 3
round 5 - 10 5 4
總合 15
const NumArray = [1,2,3,4,5];
const reducePlus = NumArray.reduce(function(accumulator, currentValue){
return accumulator + currentValue;
}, 0); //前一個值 + 現在的值 ; 初始值為0
console.log(reducePlus); // 15
練習六 - 所有Inventors共活了幾年?
有點像以前會使用for迴圈算加總一樣,reduce比較簡潔
const totalYears = inventors.reduce((accTotal , curInventor) => {
return accTotal + (curInventor.passed - curInventor.year)
},0);
console.log(totalYears) // 861
練習七 - 總結下面的陣列資料
const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck', 'pogostick'];
計算陣列內重複的個數。若陣列內index沒有項目,則新增為零,並增加項目內數量。後面的{},代表回傳的是一個物件。
const transportation = data.reduce(function(obj, item){
if (!obj[item]) {obj[item] = 0;}
obj[item]++;
return obj;
}, {});
console.log(transportation);
Array.from()
array.form 會將類陣列或可疊帶的物件,建立一個新的陣列
// array.from()基本語法
array.from(arrayLike,[mapFunction],[thisArg])
//arrayLike: 必要的參數,想要轉換成數組的偽數組對象(像是arguments)或可疊代對象。
//mapFunction: 不必要的參數,這個地方可以想成 map()的作法。
//thisArg: 不必要的參數,執行回調函數 mapFunction 時 this 對象。這個參數很少使用。
練習八: 使用參考資料,建立一個名字含有de在內的List 參考資料
做法: 將參考資料建立新陣列;從陣列取出所需的資料並排序(map);將陣列過濾出有de的名字(filter)
const category = document.querySelector('.mw-category');
const links = Array.from(category.querySelectorAll('a'));
const de = links.map(link => link.textContent).filter(streetName => streetName.includes('de'));
Array.splice()
splice() 方法可以藉由刪除既有元素並/或加入新元素來改變一個陣列的內容。
語法:
Array.splice(startIndex, replaceCount/deleteCount, item1, item2 ...)
//startIndex 從哪個索引開始執行
//replaceCount/deleteCount 要替換或刪除的數量
//items 替換或新增的值
範例:
var names=['aa','bb','cc','dd'];
names.splice(2,0,'ee');
//從索引(2),更動 0個,插入'ee'
//['aa','bb','ee','cc','dd']
names.splice(1,1,'ff');
//從索引(1)開始,更動1個(也就是更動索引(1),替換成'ff'
//['aa','ff','cc','dd']
names.splice(2,1);
//從索引(2)開始,更動(刪除)1個。
//['aa','bb','dd']