Array method! go go go!
任務拆解
- Array method
- fliter()
- map()
- sort()
- reduce()
講師設計幾組可以使用上述method的情境,比官方範例會再有感一點~
filter()
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
by -(MDN web docs)(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
一個一個元素被
指定的測試函數
篩選過濾,根據回傳值是true
/false
決定是保留還是丟掉,最後返回新陣列。
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
//output: Array ["exuberant", "destruction", "present"]
小鴨說code: 宣告words變數,記憶體位址指向一陣列,其中共有6個元素。宣告一變數result用來存結果,使用陣列filter method,測試每一個傳入的element長度是否大於6,若為true則存入result陣列中。
Filter the list of inventors for those who were born in the 1500’s
篩選出1500~1599年出生的人
const inventors = [
{ first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
{ first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
{ first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
{ first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
{ first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
{ first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
{ first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
{ first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
{ first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
{ first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
{ first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
{ first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
];
let result1 = inventors.filter((item) => {
return item.year > 1500 && item.year < 1600;
});
// or 講師解
const fifteen = inventors.filter(inventor => (inventor.year >= 1500 && inventor.year < 1600));
// 寫成arrow function 真的很乾淨
// ()=>{}
// 沒有傳入參數還是要有空括號()
// 只是回傳某個值,return可以省
// 只有一個參數,可以省()不寫
ps. console.table
將資料以表格形式呈現,乾淨無誤!
map()
The
**map()**
method creates a new array populated with the results of calling a provided function on every element in the calling array.by -(MDN web docs)(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
一個一個元素透過
運算函式
再回傳一個新的值,組成新的陣列。陣列長度不變!一對一重組一個陣列,沒回傳值就給
undefined
!
const array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
小鴨說code:宣告一變數array1,位址指向一物件,內容元素依序是1,4,9,16。使用陣列的map method,回傳結果存入map1變數中。每一個傳入的元素x,return x X 2
!
Give us an array of the inventors first and last names
取得一陣列,內容為每個發明家first name和 last name的組合!
let nameArray = inventors.map(item => item.first + ' ' + item.last);
// or 講師解
const fullNames = inventors.map(inventor => `${inventor.first} ${inventor.last}`);
// Template strings!!
// 使用``反引號
// 換行再也不用\n
// ${}可內嵌變數 or 運算式
sort()
The
**sort()**
method sorts the elements of an array in place and returns the sorted array.by -MDN web docs
直接in place改變原陣列!!
arr.sort([compareFunction])
可以傳入一comparefunction,省略不寫的話,是依據每元素轉成字串後的unicode進行排序
常見的雷是:數字排序,照數值9會在80前,但因為預設排序會先轉成字串用Unicode排序,變成80在9之前
推[JavaScript] 從 Array 的 sort 方法,聊到各瀏覽器的實作,沒想到 Chrome 和FireFox 的排序如此不同
有關compare function寫得很詳細!
節錄重點如下:
function compare(a, b) {
if (在某排序標準下 a 小於 b) {
return -1;
}
if (在某排序標準下 a 大於 b) {
return 1;
}
// a 必須等於 b
return 0;
}
另一個要小心的就是a,b分別是誰?
in chrome:
in Firefox:
懶人記法:
// 想要由小往大
arr.sort((a,b)=>a-b);
// 想要由大至小
arr.sort((a,b)=>b-a);
Sort the inventors by birthdate, oldest to youngest
出生年份由小到大排~
inventors.sort(function (a, b) {
return a.year - b.year;
})
// or 講師解
const ordered = inventors.sort((a, b) => a.year > b.year ? 1 : -1);
reduce()
The
**reduce()**
method executes a reducer function (that you provide) on each element of the array, resulting in single output value.by -MDN web docs
和前次回傳的值再進行運算,最終回傳一個運算結果!
arr.reduce(callback[accumulator, currentValue, currentIndex, array], initialValue)
const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10
// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15
accumulator:累加總值, initialvalue:累加前的初始總值, currentvalue:當下元素/變數
小鴨說code: 定義一reducer function,為每次累加當下變數進accumulator中!
How many years did all the inventors live all together?
加總全部人的歲數
const years = inventors
.map(inventor => inventor.passed - inventor.year)
.reduce((acc, cur) => acc + cur, 0);
console.log(years);
// 講師解
const totalYears = inventors.reduce((total, inventor) => {
return total + (inventor.passed - inventor.year);
}, 0);
// 每次計算歲數的結果累計至total中!
綜合情境
Sort the inventors by years lived
將實際歲數排序
const oldest = inventors
.sort((a, b) => (b.passed - b.year) - (a.passed - a.year));
console.table(oldest);
// 講師解
const oldest = inventors.sort(function(a, b) {
const lastInventor = a.passed - a.year;
const nextInventor = b.passed - b.year;
return lastInventor > nextInventor ? -1 : 1;
});
console.table(oldest);
create a list of Boulevards in Paris that contain ‘de’ anywhere in the name
取得含有de
的名稱,目標資料 https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris
- 先找出目標來源的
classname
- 觀察結構
const category = document.querySelector('.mw-category');
const links = Array.from(category.querySelectorAll('a'))
const text = links.map(item => item.textContent)
.filter(name => name.indexOf('de') > -1);
console.log(text);
// 講師解
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'));
sort Exercise Sort the people alphabetically by last name
根據每個人的last name字母做排序
const alpha = people.sort((pre, next) => {
const [preLast, nextLast] = [pre.split(', ')[0], next.split(', ')[0]];
return preLast > nextLast ? 1 : -1;
})
// 講師解
const alpha = people.sort((lastOne, nextOne) => {
const [aLast, aFirst] = lastOne.split(', ');
const [bLast, bFirst] = nextOne.split(', ');
return aLast > bLast ? 1 : -1;
});
console.log(alpha);
Reduce Exercise Sum up the instances of each of these
統計運動項目
const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car',
'truck'
];
const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car',
'truck'
];
const sum = data.reduce((obj, cur) => {
if (!obj[cur]) {
obj[cur] = 0;
}
obj[cur]++;
return obj;
}, {})
console.log(sum);
// 講師解
const transportation = data.reduce(function (obj, item) {
if (!obj[item]) {
obj[item] = 0;
}
obj[item]++;
return obj;
}, {});
小結&感想
- Array.prototype
- filter()
- 回傳新陣列
- map()
- 回傳新陣列
- sort()
- 就地改變陣列
- reduce()
- 回傳累計的accumulator
- filter()
寫code習慣很難改過來…..,落落長的寫法要慢慢精簡化!
講師的範例很實在,覺得會更知道要怎麼在實際的專案派上用場。
附上一張emoji版的講解
圖摘自Map, filter, and reduce explained using emoji
參考來源
JavaScript 陣列處理方法 [filter(), find(), forEach(), map(), every(), some(), reduce()]
[JavaScript] 從 Array 的 sort 方法,聊到各瀏覽器的實作,沒想到 Chrome 和FireFox 的排序如此不同