iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0
自我挑戰組

JavaScript 30天挑戰 自學筆記系列 第 4

JS30 自學筆記 Day04_Array Cardio Day 1

  • 分享至 

  • xImage
  •  

今日任務:認識陣列的方法

作者已先給兩個資料陣列:

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(條件)

  • 條件為true的留下,回傳新陣列,不改變原陣列
  • 適合想要過濾符合條件的資料時

範例: 找出出生於1500年裡的發明家

const fifteen = inventors.filter((inventor) => {
    if (inventor.year >= 1500 && inventor.year < 1600) {
        return true
    }
})

可簡寫為

const fifteen = inventors.filter((inventor) => 
                inventor.year >= 1500 && inventor.year < 1600)
console.table(fifteen) //可用console.table來呈現為表格

Array.prototype.map(函式)

  • 會對陣列裡每一個元素執行一次函式後,將執行結果回傳新陣列,不改變原陣列
  • 適合需要將每個元素做處理時

範例: 做一個將姓名加在一起的新陣列

const fullNames = inventors.map((inventor) => 
                  inventor.first + ' ' + inventor.last)
console.log(fullNames)

Array.prototype.sort(函式)

  • 會對陣列裡每一個元素透過函式的return進行排序後,改變原陣列
  • 如省略函式,預設將根據各元素轉為字串後的每一個字元之 Unicode 編碼位置值進行排序。
  • 適合需要將每個元素做排序時
function compare(a, b) {
 if (在某排序標準下 a 小於 b) {
   return -1;
 }
 if (在某排序標準下 a 大於 b) {
   return 1;
 }
 // a 必須等於 b
 return 0;
}

為了比較數字而不是字串,比較函式可以僅僅利用 a - b。

function compareNumbers(a, b) {
  return a - b; //由小到大
  //return b - a; //由大到小
}

範例: 根據生日從最年長排到最年輕

const ordered = inventors.sort((a, b) => {
     if (a.year > b.year) {
        return 1
    } else {
        return -1
}
console.table(ordered)

簡寫

const ordered = inventors.sort((a, b) => (a.year > b.year ? 1 : -1))
console.table(ordered)

Array.prototype.reduce(callback函式, 累加器初始值)

  • 將陣列中元素傳入函式,全部累加為一個值。
  • 適合將每個元素累加時
  • array.reduce(callback[accumulator, currentValue, currentIndex, array], initialValue)
    • accumulator : 累加器,累加器=陣列[0],如有初始值,累加器=初始值
    • currentValue : 元素
    • (選擇性)currentIndex : 元素之索引,預設從陣列[1]開始,如有初始值,預設從陣列[0]開始
    • (選擇性)array : 呼叫reduce的陣列
    • (選擇性)initialValue : 累加器初始值

範例: 將所有life加在一起

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

接下來我們來試試進入比較難的課題

題目1: 根據年紀排序 sort()

const oldest = inventors.sort((a, b) => {
     const lastInventor = a.passed - a.year
     const NextInventor = b.passed - b.year
     return lastInventor > NextInventor ? -1 : 1
})
console.table(oldest)

題目2: 做一個在巴黎大道內名字有包含'de'兩個字的清單(方法組合技)

先到這個網頁,並在這個網頁裡面找出有包含'de'兩個字的清單

取得網頁上的連結元素
const links = document.querySelectorAll('.mw-category a')
querySelectAll是一個NodeList,所以很多陣列方法不能用
將它轉成陣列
可以用Array.from,也可以使用[...]
覺得這邊用Array.from可讀性比較高,就使用Array.from
const links = Array.from(document.querySelectorAll('.mw-category a'))
const links =[ ...(document.querySelectorAll('.mw-category a')]

先用map將所有link的文字內容做成新的陣列,再用filter篩出有de的
includes() 方法會判斷陣列是否包含特定的元素,並以此來回傳 true 或 false。

const links = Array.from(document.querySelectorAll('.mw-category a'))
const de = links
    .map((link) => link.textContent)
    .filter((name) => name.includes('de'))
console.table(de)

題目3: 用lastname照著英文字母排序

people陣列裡面前後名字用", "分隔
所以先用split將", "移掉再組合
String.prototype.split([separator[, limit]])
可以用來根據你指定的分隔符號,將字串切割成一個字串陣列。

  • 參數 separator 用來指定分隔符號
  • 參數 limit 是非必要的,表示最多返回幾個分隔字串
  • split() 結果返回一個字串陣列

最後再將它們排序

const alphabet = people.sort((a, b) => {
    const [aLast, aFirst] = a.split(', ')
    const [bLast, bFirst] = b.split(', ')
    return aLast > bLast ? -1 : 1
})

題目4: 將data陣列裡的交通方式數一數各有多少

const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck', 'pogostick'];

因為我們不知道有幾種交通方式,原始值就沒辦法一個一個寫walk:0,然後再給他累加

const transportation = data.reduce((obj, item) => {
        console.log(obj, item)
        return obj
    },{
        walk:0,
        car:0...
})

所以要寫:如果沒有這種交通方式,就在物件裡新增這個交通方式walk:0,然後後面再去++
如果有的話就將那個交通方式+1(迴圈運作計算)
obj為原始值(最後"{}"就是原始值設為空物件,也就是obj原始值是空物件,然後連加)
這樣做的好處是就算之後在陣列裡面再加上其他交通方式也沒有問題

const transportation = data.reduce((obj, item) => {
    if (!obj[item]) {
     obj[item] = 0
    }
    obj[item]++
    return obj
}, {})

console.log(transportation)

今日學習到的:

  • filter(條件):想要過濾符合條件的資料時
  • map(函式):需要將每個元素做處理時
  • sort(函式):需要將每個元素做排序時
  • reduce(callback函式, 累加器初始值):將每個元素累加時
  • 轉成陣列方法:可以用Array.from,也可以使用[...]
  • includes()方法會判斷陣列是否包含特定的元素
  • split():可根據指定的分隔符號,將字串切割成一個字串陣列。

效果連結:連結

參考連結:
MDN:sort
MDN:reduce
MDN:includes
Fooish 程式技術:split


上一篇
JS30 自學筆記 Day03_Playing with CSS Variables and JS
下一篇
JS30 自學筆記 Day05_Flex Panels Image Gallery
系列文
JavaScript 30天挑戰 自學筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言