前言
昨天有一位大大丟了一個 JavaScript 問題和我一起討論,他提供了一個陣列物件給我研究看看,沒想到看似這麼簡單的東西做起來這麼麻煩,還因此耗了我大概 3~4 小時左右的時間,功力果然不夠阿~~~~~
題目
1 2 3 4 5 6
| const data = [ {id: 1, content: 'hello', category:'HTML5'}, {id: 1, content: 'hello', category:'JS'}, {id: 1, content: 'hello', category:'css'}, {id: 2, content: 'hi', category:'JS'}, ]
|
要將相同 id
底下的 category
做資料處理變成以下這樣。
1 2 3 4
| const data = [ {id: 1, content: 'hello', category:'HTML5,JS,CSS'}, {id: 2, content: 'hi', category:'JS'}, ]
|
思考
一開始我第一直覺想到 join()
,但是印象JavaScript中的 join()
與我想像的不一樣,所以上網查了一下JS 合併陣列方法。
MDN中有一個範例使用 concat()
可以合併多個陣列
1 2 3 4 5 6
| var array1 = ['a', 'b', 'c']; var array2 = ['d', 'e', 'f'];
console.log(array1.concat(array2));
|
參考
但是我看了一下覺得還是不對,因為陣列中包的是物件,所以思考一下要處理物件的方式勢必要使用到迴圈,所以又上網查了一下相關資料是否有人提供可以參考,好在查到了有人有類似的問題。
參考來源
所以依照別人提供的方式作為一個參考作了以下方式,過程為了做出這個我一度還搞不清楚狀況再 else
中又寫了一次for(let i in data)
,導致多花了許多時間。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const data = [ {id: 1, content: 'hello', category:'HTML5'}, {id: 1, content: 'hello', category:'JS'}, {id: 1, content: 'hello', category:'css'}, {id: 2, content: 'hi', category:'JS'}, ]
const cacheData = []; const newData = []; data.forEach((item) => { const str = item.id; if (typeof cacheData[str] === 'undefined') { cacheData[str] = item; } else { for (const i in data) { cacheData[str].category += `,${item.category}`; } } }); console.log(cacheData);
|
結果答案不對,所以又花了一段時間研究。
![圖片]()
後來自己試著將問題再好好花一點時間思考後才想到 for in
主要是針對物件來做處理,而本身我已經 forEach 處理陣列物件了,為什麼還需要再 for in
一次呢?,就把 for in
給去除修改成了以下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const data = [ {id: 1, content: 'hello', category:'HTML5'}, {id: 1, content: 'hello', category:'JS'}, {id: 1, content: 'hello', category:'css'}, {id: 2, content: 'hi', category:'JS'}, ]
const cacheData = []; data.forEach((item) => { const str = item.id; if (typeof cacheData[str] === 'undefined') { cacheData[str] = item; } else { cacheData[str].category += `,${item.category}`; } }); console.log(cacheData);
|
結果就出來了。
![圖片]()
但是這邊出現一個很神奇的事情,竟然第一筆資料是一個 empty
,一時之間也想不透到底原因為何,所以自己就改用另外一種方式來做處理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const data = [ {id: 1, content: 'hello', category:'HTML5'}, {id: 1, content: 'hello', category:'JS'}, {id: 1, content: 'hello', category:'css'}, {id: 2, content: 'hi', category:'JS'}, ]
const cacheData = []; const newData = []; data.forEach((item) => { const str = item.id; if (typeof cacheData[str] === 'undefined') { cacheData[str] = item; } else { cacheData[str].category += `,${item.category}`; } });
console.log(cacheData);
cacheData.splice(0,1) newData.push(cacheData);
console.log(newData);
|
這次答案就正常一點了…
![圖片]()
但是因為這種處理方式感覺很不 OK,因為所以在那邊查來查去…結果原本提問的大大就跟我說問題出在這裡 let str = item.id;
。
因為第一筆陣列是 0
,0
沒有任何資料所以才會導致出現 empty
,所以我在一次做了修改,這次就比較剪短一點。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const data = [ {id: 1, content: 'hello', category:'HTML5'}, {id: 1, content: 'hello', category:'JS'}, {id: 1, content: 'hello', category:'css'}, {id: 2, content: 'hi', category:'JS'}, ]
const cacheData = []; data.forEach((item) => { const str = item.id - 1; if (typeof cacheData[str] === 'undefined') { cacheData[str] = item; } else { cacheData[str].category += `,${item.category}`; } }); console.log(cacheData);
|
那麼這一次答案就完全正常了,也不用另外使用 splice
甚至宣告新陣列上傳。
![圖片]()
結語
基本上我在遇到問題的時候,會先思考一下有哪些方式可以用,然後將我思考的東西試著丟上 Google 來搜尋試著找看看有沒有相關問題。
當我找到這邊 參考文章 時,我研究一下裡面各種寫法,然後挑一個自己最看得懂的寫法試著刻一遍…
這次真的要反省一下只看而不思考,自己也要認真想一下人家針對的問題回答所寫的程式碼才對QQ
最後附上與我互相討論的大大部落格連結,裡面他也有思考出來的答案結果。