Navigate back to the homepage

Day4: Array Cardio 1 💪

JavaScript30
June 19th, 2021 · 1 min read

專案介紹: 練習 array 的應用,包含 filter 、 map 、 sort 、 reduce

作品頁面: https://iris1114.github.io/javascript30/04_Array-Cardio-Day-1/index.html (無畫面,請打開 console)

題目資料

題目給了 3 組資料,總共 8 道題目, inventors 資料用於 1-5 題 , people 資料用於第 7 題, data 資料用在第 8 題。

1const inventors = [
2 { first: "Albert", last: "Einstein", year: 1879, passed: 1955 },
3 { first: "Isaac", last: "Newton", year: 1643, passed: 1727 },
4 { first: "Galileo", last: "Galilei", year: 1564, passed: 1642 },
5 { first: "Marie", last: "Curie", year: 1867, passed: 1934 },
6 { first: "Johannes", last: "Kepler", year: 1571, passed: 1630 },
7 { first: "Nicolaus", last: "Copernicus", year: 1473, passed: 1543 },
8 { first: "Max", last: "Planck", year: 1858, passed: 1947 },
9 { first: "Katherine", last: "Blodgett", year: 1898, passed: 1979 },
10 { first: "Ada", last: "Lovelace", year: 1815, passed: 1852 },
11 { first: "Sarah E.", last: "Goode", year: 1855, passed: 1905 },
12 { first: "Lise", last: "Meitner", year: 1878, passed: 1968 },
13 { first: "Hanna", last: "Hammarström", year: 1829, passed: 1909 },
14];
15
16const people = [
17 "Bernhard, Sandra",
18 "Bethea, Erin",
19 "Becker, Carl",
20 "Bentsen, Lloyd",
21 "Beckett, Samuel",
22 "Blake, William",
23 "Berger, Ric",
24 "Beddoes, Mick",
25 "Beethoven, Ludwig",
26 "Belloc, Hilaire",
27 "Begin, Menachem",
28 "Bellow, Saul",
29 "Benchley, Robert",
30 "Blair, Robert",
31 "Benenson, Peter",
32 "Benjamin, Walter",
33 "Berlin, Irving",
34 "Benn, Tony",
35 "Benson, Leana",
36 "Bent, Silas",
37 "Berle, Milton",
38 "Berry, Halle",
39 "Biko, Steve",
40 "Beck, Glenn",
41 "Bergman, Ingmar",
42 "Black, Elk",
43 "Berio, Luciano",
44 "Berne, Eric",
45 "Berra, Yogi",
46 "Berry, Wendell",
47 "Bevan, Aneurin",
48 "Ben-Gurion, David",
49 "Bevel, Ken",
50 "Biden, Joseph",
51 "Bennington, Chester",
52 "Bierce, Ambrose",
53 "Billings, Josh",
54 "Birrell, Augustine",
55 "Blair, Tony",
56 "Beecher, Henry",
57 "Biondo, Frank",
58];
59
60const data = [
61 "car",
62 "car",
63 "truck",
64 "truck",
65 "bike",
66 "walk",
67 "car",
68 "van",
69 "bike",
70 "walk",
71 "car",
72 "van",
73 "car",
74 "truck",
75];

Q1. Filter the list of inventors for those who were born in the 1500’s

  • 方法 : 使用 filter() 去篩選符合條件的元素。filter() 會建立新陣列並回傳符合的元素。

  • Ans:

1const ans1 = inventors.filter((inventor) => {
2 if (inventor.year >= 1500 && inventor.year < 1600) {
3 return inventor;
4 }
5});
6
7console.table(ans1);

Q2. Give us an array of the inventors first and last names

  • 方法: 使用 map() 回傳 inventors 的 first last names 。map() 也會產生新陣列,並回傳你所需要的值。

  • Ans:

1const ans2 = inventors.map((inventor) => {
2 return `${inventor.first} ${inventor.last}`;
3});
4
5console.table(ans2);

Q3. Sort the inventors by birthdate, oldest to youngest

  • 方法: 使用 sort() 排序生日。sort() 則不會產生新陣列, 對原陣列進行排序,並回傳此陣列。 但要注意的是排序不一定穩定,排序順序是根據字串的 Unicode 編碼位置而定。

  • Ans:

1const ans3 = inventors.sort((a, b) => {
2 return a.year - b.year;
3});
4
5console.table(ans3);
  • 補充:
1const array1 = [1, 30, 4, 21, 100000];
2array1.sort();
3console.log(array1);
4// expected output: Array [1, 100000, 21, 30, 4]

以上例子,不是我們預想的排序,因為元素將被轉換為字串並以 Unicode 編碼位置進行比較來排序。所以這時候我們就需要使用compareFunction 來做比較。

語法: arr.sort([compareFunction])

如果 compareFunction 被應用,陣列元素們將根據比較函式之回傳值來排序。如果 a 和 b 為被比較之兩元素, a 小於 b ,則 a 排在 b 前面。 a 大於 b, 則 a 排在 b 後面。回傳 0,則 a 與 b 皆不會改變彼此的順序。

函式會是以下形式(用於第 7 題作法):

1function compare(a, b) {
2 if (在某排序標準下 a 小於 b) {
3 return -1;
4 }
5 if (在某排序標準下 a 大於 b) {
6 return 1;
7 }
8 // a 必須等於 b
9 return 0;
10}

為了比較數字而不是字串,比較函式可以僅僅利用 a 減 b。以下函式將會升冪排序陣列(用於第 3 題、第 5 題作法):

1function compareNumbers(a, b) {
2 return a - b;
3}

因為第三題只需要數字比較,我這邊就使用 a 減 b 進行排序。


Q4. How many years did all the inventors live all together?

  • 方法: 使用 reduce 來計算他們總共幾歲。reduce() 跟其他陣列方法(例如:map、filter)的差別是它會 return 一個值,而不是一個新陣列。不過一般我們也可以使用 forEach 進行加總也可以。

  • Ans:

1const ans4 = inventors.reduce((total, inventor) => {
2 return total + (inventor.passed - inventor.year);
3}, 0); //從0開始+
4
5console.log(ans4);
6
7//forEach 方法
8
9let total = 0;
10inventors.forEach((inventor) => {
11 total += inventor.passed - inventor.year;
12});
13console.log(total);
  • 補充

語法: Array.reduce(callback[accumulator, currentValue, currentIndex, array], initialValue)

accumulator:經由個別 currentValue 加總的累計值

initialValue:預設值,放在 function 的最後方,非必填

若未提供預設值:

1const arr = [1, 2, 3, 4, 5];
2const reduceArr = arr.reduce((accumulator, currentValue) => {
3 return accumulator + currentValue;
4});
5console.log(reduceArr); // 15

上述範例若未提供預設值,accumulator(累計值)就會取陣列的第一個元素也就是 1,而 currentValue 就會從陣列的第二個值開始 loop。

若加上預設值 0 :

1const arr = [1, 2, 3, 4, 5];
2const reduceArr = arr.reduce((accumulator, currentValue) => {
3 console.log(accumulator); // 0, 1, 3, 6, 10
4 console.log(currentValue); // 1, 2, 3, 4, 5
5 return accumulator + currentValue;
6}, 0);
7console.log(reduceArr); // 15

他就會從 0 開始加起,再繼續從陣列第一個值 loop 下去。

他也可用於合併陣列 :

1const arr = [
2 ["a", "b"],
3 ["c", "d"],
4 ["e", "f"],
5];
6const reduceArr = arr.reduce((accumulator, currentValue) => {
7 return accumulator.concat(currentValue);
8}, []);
9console.log(reduceArr); // ['a', 'b', 'c', 'd', 'e', 'f'];

Q5. Sort the inventors by years lived

  • 方法:使用 sort() 排序他們的壽命。
  • Ans:
1//新增他們壽命,來檢查排序是否有錯誤
2inventors.forEach((inventor) => {
3 inventor.age = inventor.passed - inventor.year;
4});
5
6const ans5 = inventors.sort((a, b) => {
7 return a.passed - a.year - (b.passed - b.year);
8});
9
10console.table(ans5);
  • 第三題已有針對 sort() 進行補充,這題多了計算壽命的部分。

Q6. create a list of Boulevards in Paris that contain ‘de’ anywhere in the name

  • 方法: 從這個網站中 list 找出含’de’字眼的街道名稱。 先用 querySelectorAll 找出所有 list , 但找到的 list 不是 array, 他是 nodelist, 無法進行 mapping, 所以可以使用 Array.from 將 nodeList 轉為 Array。 或是 nodelist 也可以使用 forEach 跑 loop。
1// method1
2const array = [];
3const lists = document.querySelectorAll(".mw-category li a"); //nodelist 不是陣列,但可以用 forEach 跑迭代, 可以用 array from
4
5lists.forEach((list) => {
6 array.push(list.title);
7});
8
9const ans6 = array.filter((title) => {
10 return title.indexOf("de") !== -1;
11});
12
13console.log(ans6);
14
15//method2
16const category = document.querySelector(".mw-category");
17const links = Array.from(category.querySelectorAll("a"));
18const de = links
19 .map((link) => link.textContent)
20 .filter((streetName) => streetName.includes("de"));

Q7. Sort the people alphabetically by last name

  • 方法: 使用 people 資料的 last name 進行排序, 一樣是使用 sort, 可參考第三題補充, 但因為他是文字, 使用我們 compareFunction(a, b) 函式進行排序。

  • Ans:

1const ans7 = people.sort((a, b) => {
2 const [aFirtst, aLast] = a.split(", ");
3 const [bFirtst, bLast] = b.split(", ");
4
5 return aLast > bLast ? 1 : aLast < bLast ? -1 : 0;
6});
7
8console.log("7. Sort the people alphabetically by last name");
9console.log(ans7);

Q8. Sum up the instances of each of these

  • 方法: 使用 data 資料的來計算裡面相同東西的數量,剛剛上面 reduce() 沒提到的應用, 他也可以計算相同字串的數量並以物件呈現。

  • Ans:

1const ans8 = data.reduce((obj, content) => {
2 if (!obj[content]) {
3 //如果沒有的話則為0
4 obj[content] = 0;
5 }
6 obj[content] += 1; //如果沒有的相同的則+1
7
8 return obj;
9}, {}); //預設給個空object
10
11console.log(ans8);

這篇部落格花我好多時間,比寫 code 時間還久很多很多 XD 終於完成,繼續加油!

More articles from Iris Blog

Day3: CSS Variables

使用 JavaScript 及 CSS3 去調整圖片的邊框間距、模糊度、及背景顏色,標題 JS 也隨著背景顏色而改變。

June 17th, 2021 · 1 min read

Day2: JS and CSS Clock

專案介紹: 實作一個時鐘。

June 15th, 2021 · 1 min read
© 2020–2021 Iris Blog
Link to $mailto:qweichew@gmail.comLink to $https://github.com/iris1114Link to $https://www.instagram.com/iris.justdoit/Link to $https://www.linkedin.com/in/iris-chew