JavaScript30 為Wes Bos推出的一項為期30天的挑戰,旨在幫助人們用純JavaScript來實現效果,初學者若想在JS方面快速精進,不妨一試。現在你看到的是該系列總結的第一篇,不知何時能做完30題,就不在此信誓旦旦立flag了。本題為第四題。
實現效果
本章節是為介紹JS Array的幾個常用方法,包含filter(),map(),sort(),reduce(),並在 Console 皮膚中檢視結果。其中文件已給出兩組陣列:
- 第一組:inventors陣列,包含名、姓、出生日期以及死亡日期
const inventors = [
{ first: `Albert`, last: `Einstein`, year: 1879, passed: 1955 },
......
{ first: `Hanna`, last: `Hammarström`, year: 1829, passed: 1909 }
];
複製程式碼
- 第二組:people陣列,包含一組人名,名姓之間用逗號分隔。
const people = [`Beck, Glenn`, ...... , `Blake, William`];
複製程式碼
題目如下:
- 篩選出生於16世紀的發明家;
- 以陣列形式,列出其名與姓;
- 根據其出生日期,並從大到小排序;
- 計算所有的發明家加起來一共活了幾歲;
- 按照其年齡大小排序;
- 利用給出的網站(https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris),列出包含`de`位元組的巴黎大道;
- 按照姓氏排序;
- 統計出陣列中每個種類的數量。
知識點
filter()
過濾操作,篩選符合條件的所有元素,若為true則返回組成新陣列,以第一題為例:
function bornyear(inventor) {
return inventor.year >= 1500 && inventor.year < 1600;
}
var fifteen = inventors.filter(bornyear);
console.table(fifteen);
// 可簡化為
const fifteen = inventors.filter(inventor => (inventor.year >= 1500 && inventor.year < 1600));
複製程式碼
map()
對映操作,對原陣列每個元素進行處理,並回傳新的陣列。以第二題為例:
const fullnames = inventors.map(inventor => `${inventor.first} ${inventor.last}`);
console.table(fullnames);
複製程式碼
sort()
排序操作,預設排序順序是根據字串Unicode碼點,如10在2之前,而數字又在大寫字母之前, 大寫字母在小寫字母之前。也可使用比較函式,陣列會按照呼叫該函式的返回值排序,格式如下:
function compare(a, b) {
if (a < b) {
// 按某種排序標準進行比較, a 小於 b
return -1;
}
if (a > b) {
return 1;
}
// a must be equal to b
return 0;
}
複製程式碼
要比較數字而非字串,比較函式可以簡單的以 a 減 b,如下的函式將會將陣列升序排列:
function compareNumbers(a, b) {
return a - b;
}
複製程式碼
針對第三題,我們就可以簡單用加減比較:
const birthdate = inventors.sort((inventora, inventorb) => (inventorb.year - inventora.year));
console.table(birthdate)
複製程式碼
而第七題,則需要按返回值比較:
const sortName = inventors.sort((a, b) => {
return (a.last > b.last) ? 1 : -1;
})
console.table(sortName);
複製程式碼
reduce()
歸併操作,總共兩個引數,第一個是函式,可以理解為累加器,遍歷陣列累加回傳的返回值,第二個是初始數值。如果沒有提供初始值,則將使用陣列中的第一個元素。以第四題為例:
const totalyears = inventors.reduce((total, inventor) => { return total + (inventor.passed - inventor.year); }, 0);
console.log(totalyears);
複製程式碼
reduce()方法講同樣用於第八題:
const sumup = data.reduce(function (obj, item) {
if (!obj[item]) {
obj[item] = 0;
}
obj[item]++;
return obj;
}, {});
console.log(sumup);
複製程式碼
值得注意的是,回撥函式的第一個引數也可以為物件,儲存每一類物品的數量。關於物件,如需深入理解,可參考阮一峰的部落格。
map()與filter()結合
參考第六題,題目要求在該網站篩選出含有`de`位元組的巴黎大道;首選取得對應節點的元素,並轉化為陣列,再利用.includes()方法就可以得到。
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`));
console.table(de)
複製程式碼
複製程式碼