0%

JavaScript-Array-Cardio-Day1-04

這是一個關於畢業的時候的回憶,
還記得那時候根本不知道自己要做什麼,所以什麼領域的工作的投投看,
去面了各種各樣的工作,MA, FinTech, traders, Financial researcher, Risk management, pytheon data enginner, java enginner, IC designer …

最後選擇一個環境很歡樂的公司大家都是像是很好的朋友一樣。

一開始雖然自己的成長沒有很快,可能是因為在這裡沒有沒帶我又是一個什麼都不太懂的菜菜,
剛出社會覺得什麼事情都要好好把握,好好表現,不敢問一些問題不懂就先說大概懂,
也許就是因為這樣的個性,讓我係在可以成長得比別人快吧,

反正不會什麼都不懂就去google, 然後練習codeing,
還記得那個時候我因為知道自己沒有什麼能力,所以每天下班回家都去練習寫leetcode,
什麼都不懂,也不知道要怎麼google,看不懂語法,看不懂函式,最慘的連題目都看不懂,
所以這次的題目讓我覺得很有感觸,
以前花了這麼多時間還是似懂非懂的東西,現在居然可以直接寫出來,
大家都做得到的事情,我們要做的比別人更好
覺得基本的函式已經得心應手了,就試試看ES6來寫寫看吧
有在看這篇的人,如果覺得自己不是寫程式的料,
請再堅持三個月,有一天你就會突然,真的是突然融會貫通了。
在你們要放棄的時候,請想想這裡還有一個一直不斷堅持,三點半的靈魂。

1
2
3
4
5
6
7
8
9
10
11
12
未知的每一步,永遠不知道做了決定會不是錯的,儘管當下看上去是最順遂的路,
但沒有人知道實際上會不會有陷阱,
不知道勇敢提出意見會不會被覺得強出風頭;
不知道勇敢開口約女生會不會被覺得,你想多了我才對你沒興趣。
不知道真的約出來之後,只是個值得信賴的好朋友,還是一個可靠的肩膀。
總是有太多的不確定,沒有人知道這些不知道會導致什麼後果,所以遲遲不前選擇安穩。
人生就是不斷的後悔,但有些事情如果你不去試試看,會連後悔的資格都沒有,
最近開始想著完成去年剛接觸軟體時想著要完成一個可以賣錢的產品,
儘管一切都想的很不全面,但原地踏步光是空想就是退步吧。
那就開始執行吧,不管是夢想,還是那個心儀的人,
跨出去就有機會,失敗了就再努力一次,
當自己走向越來越好的獨一無二,就在給自己一次機會再放手去努力一次也無仿。

希望現在的我在別人眼中,也許不是一個很棒的人,但一定是最努力的那一個。

04 - Array Cardio Day 1

首次上傳:2020/09/04

主題

作者用了8個範例來介紹關於Array的各種操作。

步驟

練習範例內有提供了3組資料:

  1. inventors:first(名)、last(姓) 、year(出生日期)、passed(逝世日期)
  2. people:逗點分隔的姓名(firstName, lastName)
  3. data:在練習8中提供的一組包含重覆資料的陣列

要練習的題目為:

  1. 篩選出於1500~1599年間出生的inventor(year in 1500-1599)
  2. 將inventors內的first與last組合成一個陣列
  3. 依據生日由大至小排序所有的inventor
  4. 加總所有inventor的在世時間
  5. 依據年齡由大至小排序所有的inventor
  6. 列出wiki中巴黎所有包含’de’的路名(在wiki中透過querySeslectorAll來選取資料作篩選)
  7. 依據lastName排序所有people的資料
  8. 分別計算data內每個種類的數量

新的developer tool

  1. console.log() -> 會顯示一串Array 但不好看
  2. console.table(‘Array_name’) -> 會是一個sheet

JavaScript語法&備註

1. filter()

題目:篩選出於1500~1599年間出生的inventor(year in 1500-1599)
解答:透過fifter()對來源做篩選,會將結果為true的資料組成陣列回傳

1
2
3
4
5
6
7
const fifteen = inventors.filter(function(inventor) {
if(inventor.year >= 1500 & inventor.year <= 1600) {
return true;
}
});
//可簡化為arrow function
const fifteen = inventors.filter(inventor => (inventor.year >= 1500 & inventor.year <= 1600));

參閱:MDN-Array.prototype.filter()

2. map()

題目:將inventors內的first與last組合成一個陣列
解答:透過map來將firstName/lastNam組合返回陣列

1
2
const fullNames = inventors.map(inventor => `${inventor.first} ${inventor.last}`);
console.log(fullNames);

參閱:MDN-Array.prototype.map()

2.1 forEach()

map() 可以針對return的東西產一個新陣列
forEach() 沒有回傳值 比較像是對回傳的東西 各做一件事, 不能控制非同步 (比較難控制順序問題)

1
2
3
let ans_2 = []
inventors.forEach(inventor => ans_2.push(inventor.first + ' ' + inventor.last))
console.table(ans_2)

3. sort()

題目:依據生日由大至小排序所有的inventor
解答:透過sort()來做排序
Ex:

1
2
3
4
let array =[2, 5, 3, 7, 6]
let ans = array.sort()
console.log(ans)
// 2, 3, 5, 6, 7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const ordered = inventors.sort(function(a, b) {
if(a.year > b.year) {
return 1;
} else {
return -1;
}
});
//利用箭頭函式及三元運算式可簡寫如下
const ordered = inventors.sort((a, b) => a.year > b.year ? 1 : -1);
`````
>若比對的值相同要依據原排序的話,要再加上一個`return 0`的判斷使其保持原排序
>參閱:[MDN-Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)


### **4. reduce()**
題目:加總所有inventor的在世時間
解答:要加總的話,用以前的寫法會寫這樣
````javascript
let totalYears = 0;
for (let i = 0; i < inventors.length; i++) {
let liveYear = inventors[i].passed - inventors[i].year;
totalYears += liveYear;
}

如果利用reduce()搭配箭頭函式如下:

1
2
3
const totalYears = inventors.reduce((total, inventor) => {
return total + (inventor.passed - inventor.year);
}, 0);

redice()的callback有四個參數:

  1. 初始值
  2. 陣列中正在處理的元素
  3. 陣列中正在處理的元素的索引值(好饒舌XD)
  4. 使用reduce的陣列
    及一個預設值(會再第一次執行時賦予第一個參數設定的值。

所以用這個答案來看,在第一次執行時預設值賦予了total=0
接著每次讀取陣列元素時對其計算在世時間並加回total中。

參閱:MDN-Array.prototype.reduce()

5. sort()

題目:依據年齡由大至小排序所有的inventor。
解答:排序原理同第三題,多了一段計算年齡的部分而已

1
2
3
4
5
const oldest = inventors.sort(function (a, b) {
const lastInventor = a.passed - a.year;
const nextInventor = b.passed - b.year;
return lastInventor > nextInventor ? -1 : 1;
});

6. map() + filter() & includes()

題目:列出wiki中巴黎所有包含’de’的路名
解答:

1
2
3
4
5
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'));

這題先用querySelectorAll()來選取對象元件,
再利用之前第一個練習有提到的Array.from將nodeList轉為Array,
才能對其進行map操作(map是Array的方法,nodeList沒有),
同時加上filter+includes來做文字的篩選,若存在’de’就回傳true加入陣列。

參閱:MDN-Array.prototype.includes()

7. sort() & split()

題目:依據lastName排序所有people的資料
解答:

1
2
3
4
5
const alpha = people.sort((lastOne, nextOne) => {
const [aLast, aFirst] = lastOne.split(', ');
const [bLast, bFirst] = nextOne.split(', ');
return aLast > bLast ? 1 : -1;
});

由於people的資料都是['Beck, Glenn’]這樣的逗點字串,
要取得lastName就必須要使用split()來切開,
滿酷的是因為split()會返回陣列,所以宣告了陣列[aLast, aFirst]來接值
接著再利用接到的值來做排序比對。

參閱:MDN-String.prototype.split()

結構附職 : EX

1
2
3
4
5
let ary = '1,2,3,4,5,6'
let [first, second,...third] = ary.split(',')
console.log(first) // 1
console.log(second) // 2
console.log(third) // 3,4,5,6

8. reduce()

題目:分別計算data內每個種類的數量
解答:

1
2
3
4
5
6
7
8
9
const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck', 'pogostick'];

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

這題的做法真的很厲害啊!
首先利用預設值將reduce()的第一個參數設定為空物件obj={}
接著做一個判斷來決定建立物件內容或著使已建立內容累加總數!

探索

將上面用到的技巧應用到一個常會遇到的統計問題
題目:試著將統計people的所有單字拆開,並統計各單字共出現次數(僅包含英文字)
解答:

1
2
3
4
5
6
7
8
9
10
11
const strCnt = people.reduce(function (obj, item) {
const itemStr = item.match(/[a-zA-Z]/g, '');
itemStr.forEach(str => {
if (!obj[str]) {
obj[str] = 0;
}
obj[str]++
})
return obj;
}, {});
console.log(strCnt);

同第8題,先宣告一個空陣列來傳入item,
接著將每個item透過match()拆開只取英文字,
再利用forEach來建立內容或是累加總數。

[DEMO]