iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
JavaScript

火箭通關JS30系列 第 4

JS30-04 - Array Cardio Day 1

  • 分享至 

  • xImage
  •  

課程目的:

這次的內容是,給我們兩個陣列讓我們對array使用不同的methods去達成我們的題目要求

接下來就讓我們去試著運用array.method!
實做連結

本次功能實作重點:

  1. Array.prototype.filter()
  2. Array.prototype.map()
  3. Array.prototype.sort()
  4. Array.prototype.reduce()
  5. Sort the inventors by years lived*
  6. create a list of Boulevards in Paris that contain 'de' anywhere in the name
  7. sort Exercise
  8. Reduce Exercise
      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 },
      ];

      const people = [
        "Bernhard, Sandra",
        "Bethea, Erin",
        "Becker, Carl",
        "Bentsen, Lloyd",
        "Beckett, Samuel",
        "Blake, William",
        "Berger, Ric",
        "Beddoes, Mick",
        "Beethoven, Ludwig",
        "Belloc, Hilaire",
        "Begin, Menachem",
        "Bellow, Saul",
        "Benchley, Robert",
        "Blair, Robert",
        "Benenson, Peter",
        "Benjamin, Walter",
        "Berlin, Irving",
        "Benn, Tony",
        "Benson, Leana",
        "Bent, Silas",
        "Berle, Milton",
        "Berry, Halle",
        "Biko, Steve",
        "Beck, Glenn",
        "Bergman, Ingmar",
        "Black, Elk",
        "Berio, Luciano",
        "Berne, Eric",
        "Berra, Yogi",
        "Berry, Wendell",
        "Bevan, Aneurin",
        "Ben-Gurion, David",
        "Bevel, Ken",
        "Biden, Joseph",
        "Bennington, Chester",
        "Bierce, Ambrose",
        "Billings, Josh",
        "Birrell, Augustine",
        "Blair, Tony",
        "Beecher, Henry",
        "Biondo, Frank",
      ];

首先原作者給我們兩個陣列,接下來我們要用這兩個物件去依照題目做相應的處理~

Array.prototype.filter()

用途: arr.filter(),會遍歷arr中的元素驗證函式內部自訂的條件,若有元素有通過檢驗則會回傳其元素為一個新陣列

改變:不會改變元陣列,所以需要用一個變數去接住

題目:

1.Filter the list of inventors for those who were born in the 1500's
1.篩選 1500 年代出生的發明家列表

let ans = inventors.filter(
        (inventors) => inventors.year >= 1500 && inventors.year <= 1600
      );
      console.log(ans);

1500年代出生代表著1500~1600之間出生的發明家,而inventors的物件屬性year,代表著每個人的出生年份,於是寫判斷式為inventors.year >= 1500 && inventors.year <= 1600,這樣可以篩選出我們想要的資料!

Array.prototype.map()

用途: arr.map(),會遍歷arr中的每個元素經由回呼函式運算回傳的結果傳入新的array

改變:不會改變元陣列,所以需要用一個變數去接住

題目:

2.Give us an array of the inventors first and last names
2.給我們一系列發明人的名字和姓氏

let name = inventors.map((e) => e.first + " " + e.last);
      console.table(name);

這個題目要我們做的是印出發明人的姓名,而inventors的物件屬性first及last各自指的是它們的姓氏與名字,於是取陣列每個物件(e)中的e.first + " " + e.last ,這樣就可以將我們的名字組起來了!

Array.prototype.sort()

用途: arr.sort(),可以利用回呼函式定義元素的排序,若沒定義則會依據字串的 Unicode 編碼進行排序

改變:會改變元陣列

題目:

3.Sort the inventors by birthdate, oldest to youngest
3.依出生日期對發明人進行排序,從最年長到最年輕

 let years = inventors.sort((a, b) => a.year - b.year);
      console.table(years);

在sort()中a - b為升冪,b-a為降冪,而我們要的是最年長到最年輕的發明人,這代表越早出生的人會越年長,於是我們寫函式為a.year - b.year(由數字小到大排序)

Array.prototype.reduce()

用途: 方法將一個累加器及陣列中每項元素(由左至右)傳入回呼函式,將陣列化為單一值。這個方法會返回最終的累加結果。

改變:不會改變元陣列

功能:

arr.reduce(
 (accumulator, currentValue, currentIndex, array), initialValue)

accumulator :作為一個累加器,若沒特別設定的話則Array[0]為初始值

currentValue:當前陣列迭代元素的值

currentIndex : 當前元素在陣列中的索引,非必要數值

array: 調用 reduce() 的陣列,非必要數值。

initialValue:設定accumulator的初始值,若沒有設定的話則以Array[0]作為累加,並以Array[1]作為currentValue

題目:

4.How many years did all the inventors live all together?
4.所有發明家總共活了幾年?

 let total = inventors.reduce((total, inventors) => {
        return total + inventors.passed - inventors.year;
      }, 0);
      console.log(total);

因為我們要計算每個發明家總共活了幾年,所以先設定initialValue 為0,inventors.passed這個屬性是指發明家逝世的年份,要算出各個**發明家活著的歲數=逝世的年份-出生的年份,total作為累加器+**逝世的年份-出生的年份,則會回傳發明家活著的總年齡

題目:

5.Sort the inventors by years lived
5.按壽命對發明家進行排序

html
let totals = inventors.sort((a, b) => {
        return (a.passed - a.year) - (b.passed - b.year);
      });
      console.table(totals);

在前面的題目我們知道了發明家的壽命是逝世的年份-出生的年份,如果我們要由壽命短~到壽命長來排序,在sort()這個函式排序我們要用升冪的方式,也就是a-b,再套入我們想要排序的屬性(a.passed - a.year) - (b.passed - b.year),比較各個壽命的長短,這樣可得壽命短~壽命長的順序

題目:

6.create a list of Boulevards in Paris that contain 'de' anywhere in the name
6.建立巴黎大道列表,名稱中任意位置包含“de”

https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris

html
let arr = [];
      document.querySelectorAll(".mw-category-group li a").forEach((e) => {
        arr.push(e.title);
      });
      let anss = arr.filter((e) => e.indexOf("de") !== -1);
      console.log(anss);

這個題目叫我們進入作者給的維基百科內取得**巴黎所有的林蔭大道,**並且取得包含”de”的元素並放進新的array中,我們要在網址F12的主控台執行

image.png

先命名一個變數arr,賦值為一個空陣列,用檢查點選我們要的標籤,發現每一個地區都是包裹在div.mw-category li裡面的a連結,querySelectorAll選取我們要的元素(".mw-category-group li a"),因為這些元素是複數所以要利用forEach將a的title放進空陣列arr裡,故arr這時候裡面會是所有巴黎的林陰大道

這時候再利用arr.filter並且寫函式e.indexOf("de") !== -1 :意思是只要 "de" 出現在字符串中的任何位置,就會返回 true。反回true的元素則會儲存在anss的變數內

7.sort Exercise
Sort the people alphabetically by last name
7.排序練習
按姓氏字母順序對人員進行排序

html
  let names = people.sort((a, b) => {
        let [aFirst, aLast] = a.replace(" ", "").split(","); //將空白替代成"" 將字串分開成兩部分
        let [bFirst, bLast] = b.replace(" ", "").split(",");

  
        return aLast[0].localeCompare(bLast[0]);
      });

先看看我們people內的[0]為"Bernhard, Sandra",因為我們要的是姓氏Sandra的地方,去與其他姓氏排序A~Z

所以我們先命名一個陣列let [aFirst, aLast] = a.replace(" ", "").split(",");:

  • a.replace(" ", ""):將字符串 a 中的空格移除
  • .split(","):將字符串 a 按照逗號 , 分成兩部分,前面是名字(aFirst),後面是姓氏(aLast

於是b也做相同的處理

最後return aLast[0].localeCompare(bLast[0])

localeCompare 會比對字串的字典順序,我們用aLast[0] 去比對bLast[0] ,如果a在b前的字母則a 排在 b 之前,反之

這樣我們就可以得到一串姓氏由A~Z排序的姓名陣列了

  1. 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",
      ];
      let sum = data.reduce((obj, content) => {
        //假如物件中還沒有該屬性 便創造該屬性且值為0
        if (obj[content] === undefined) {
          obj[content] = 1;
        } else {
           obj[content] += 1;
        }
        return obj;
      }, {});

這個題目是要求我們把data內算出重複字串總結為多少,列如car:5 truck:3,第一個想到的是可以使用我們的reduce(),我們設定初始值obj ={},並寫判斷式

html
if (obj[content] === undefined) {
          obj[content] = 1;
        } else {
           obj[content] += 1;
        }

如果我們的obj內部找不到[content]屬性,則設定其值為1,如果有的話則累加obj[content]+=1,這樣就可以計算我們的各式有幾個元素並且累加其值

導讀文件以及學習資源

JS30
[ Alex 宅幹嘛 ] 👨‍💻 深入淺出 Javascript30 快速導覽:Day 4:Array Cardio Day 1


上一篇
JS30-03-CSS Variables
下一篇
JS30-05 - Flex Panel Gallery
系列文
火箭通關JS3030
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言