[初探後端]No.5 遇到程式問題,如何把問題切細變得容易解決

前言

No.4 寫完之後,我果然還是很在意自己這樣子寫可不可以,於是我就請了一位大大來幫我看看,是不是有哪些地方可以調整,然後給了我三個建議。

前情提要一下

[初探後端]No.4 對文章加上多個分類

  • ref 表名字可以換一下,太臭長了
  • 更新的部份,因為知道原始分類、也知道目標所以可以想成這樣
    • source: 1, 2, 3
    • target: 1, 3, 5, 7

      寫出來就能比較清楚知道要保留、刪除、新增哪些。
      而我之前的做法是無差別刪除,然後新增 (比較簡單、偷吃步)

  • 取得文章可以不用連這麼多次資料庫,試著練習資料結構處理

從資料庫取得的資料

因為本身還在學習 PHP ,所以對 PHP 語法可能不夠熟悉,因此不知道如何動手,所以才有那種相當耗資源的寫法。於是給我建議的大大說,那不然你把它想成這樣的結構

1
2
3
4
5
6
7
8
9
10
11
12
[  
{id: 1, content: 'hello', category: 'HTML'},
{id: 1, content: 'hello', category: 'JS'},
{id: 1, content: 'hello', category: 'CSS'},
{id: 2, content: 'hi', category: 'CSS'},
]

// 處理成下面這樣
[
{id: 1, content: 'hello', category: 'HTML,JS,CSS'},
{id: 2, content: 'hi', category: 'CSS'},
]

試著用 JavaScript 去把這個資料轉化成你想要的樣子

老實說我這題卡了 6 小時,看起來需求很簡單,不過實際上當真的要動手寫的時候,會發現腦袋幾乎是空白的,再次驗證程式不能只用看的、想的,要真的動手寫。

一開始,我把注意力都放在 ES5、6 的陣列方法上, 像是 reducefilterforeach 等等,怎麼樣就是不知道該怎麼繼續做下去。

也查了一些什麼物件合併、陣列合併的方法,但好像有看跟沒看一樣。

後來大大給了我其他的提示:

  • 不要想成直接把 A 轉成 B ,想成如何利用 A 的資訊,重新建構出一個你想要的 B
  • 資料結構先改成以下,先想辦法拼湊成這樣
  • 不要去想什麼陣列方法,這題用 for 迴圈就能解決
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [  
    {id: 1, content: 'hello'},
    {id: 2, content: 'hi'},
    ]

    // 處理成下面這樣
    {
    1: {
    content: 'hello'
    },
    2: {
    content: 'hi'
    }
    }

於是我好不容易拼湊出來了,在卡了好一陣之後。

1
2
3
4
5
6
7
8
9
let dataLen = data.length;  
let obj = {};

for(let i = 0; i < dataLen; i++){
id = data[i].id;
obj[id] = {content: data[i].content};
}

console.log(obj);

接著說也奇怪,我似乎慢慢地知道該怎麼做了,於是我把資料補回原本的那樣,然後繼續維持輸出成物件的形式。

  • 因為我要跑 for 迴圈,肯定要知道這個陣列的長度
  • 接著最困難的點就是,要怎麼判斷「當前 data 陣列內 的這個物件跟下一個物件是不是一樣的」

如果一樣,需要對分類做合併;不一樣就新增

對於第二點,我的做法是使用「type of 檢查 obj 物件,如果物件內沒有對應的 id 屬性,會顯示 undefined ,代表這筆資料是不同的,必須新增

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let data = [  
{id: 1, content: 'hello', category: 'HTML'},
{id: 1, content: 'hello', category: 'JS'},
{id: 1, content: 'hello', category: 'CSS'},
{id: 2, content: 'hi', category: 'CSS'},
]

let dataLen = data.length;
let obj = {};
for(let i = 0; i < dataLen; i++){
if(typeof obj[data[i].id] === 'undefined'){
obj[data[i].id] = {
content: data[i].content,
category: data[i].category
};
} else {
obj[data[i].id].category = `${obj[data[i].id].category},${data[i].category}`;
}
}
console.log(obj);

後來我覺得還是把 id 也包進物件內好了,所以又自己補上去。

到這邊就整個都通了,接著要把它換成一開始要求的樣子,於是我查到一個好用的方法 Object.values() ,補上即可轉換。

1
2
let arr = Object.values(obj)  
console.log(arr);

後記

最困難的部分已經克服了,接著就是要回到 PHP 實作,邏輯基本上都沒變,只是語法要稍微調整一下,相信不是太大問題。

最後 PHP 部份我也順利的完成了,這一篇主要記錄的是「當遇到問題,如何把問題切細,變得容易解決」,非常感謝給我建議的大大,也花了不少時間引導我。

0%