專案中遇到一個陣列方法綜合運用的情境,紀錄一下。
資料有兩個陣列,一個是 info、一個是 node,可以看到兩個是不同的長度。
情境
使用 Angular8 開發,因要用 D3.js 繪製流程圖,需求主要為 node 作為繪製流程的節點,並且使用 info 呈現目前節點狀態,若 info 沒有資料代表流程上為跑到,但節點要先顯示,有點像購物網站進度條的概念。
因有許多頁面需要使用到此資料處理邏輯,所以拉出來做共用元件,讓資料丟進來後可以傳給 D3.js 正確顯示。
資料
1 | info = [ |
- 命名兩個變數,分別取得資料內容(當作已經打 API 回來的狀態)
- newArr 是等等重組完要用的空陣列。
1 | let node = this.node; |
使用 find 找到屬性欄位
有提到 node 為主要節點,所以先用這個資料用
forEach
遍歷每一筆資料。先找子節點,建立一個子節點的陣列,要來放等等子節點的資料。
原因是陣列資料主節點為主要狀態節點,Children 屬性為下一個節點要去的值,這樣流程才會正確呈現。
子節點 item.children 跑 forEach 去找出所有的子節點屬性的值。
宣告一個 currentChild 子節點結果去儲存
find
的結果,使用find
去找到 info 的節點 now_node 欄位是否有跟子節點 childrenNameNode 的值一樣,有的話就回傳 true。
find
方法會找到第一筆相符的條件後,回傳 true,透過console.log()
去看會發現是一個物件型態。
1 | node.forEach((item) => { |
- 宣告一個 childStatus 子節點狀態的變數,並且判斷 currentChild 是
truthy
或是falsy
。若為truthy
,就使用push
把資料放到 childrenList 的陣列中。 - 最後需求有規定一個物件格式,所以重新宣告一個 childNode 變數去儲存新的物件格式。
!!
兩個驚嘆號是快速讓變數變成布林值的寫法,等價於new Boolean()。
1 | let childStatus = !!currentChild ? currentChild.node_action : undefined; |
以上使用了
forEach
、find
、push
三種方法以及boolean
值轉換的方式。
- 主節點的資料整理方式與子節點相同。
1 | let currentMain = info.find((main) => main.now_node === item.node); |
最後宣告一個要傳資料到 D3.js 的全域變數 nodeArr,其屬性為空陣列。
1 | nodeArr: any[] = []; |
並把剛剛組好的 newArr 賦值給 nodeArr,下面為節點取值的完整程式碼。
1 | let node = this.node; |
組出已審核節點資訊
節點資訊有分成兩種,一種是流程已經跑到會出現資訊,另一個是流程還沒到,雖然有節點,但不會有節點資訊,有點像是購物車狀態,還沒進行到的部分會顯示該筆狀態,但不會有進度資訊。
- 宣告一個空陣列變數 infoList,並且用原本資料的 info 去跑
forEach
,把每一筆資料的內容抓出來。 - 因需求也是要重組一個資訊內容,這邊在宣告一個空陣列 mainInfo,要放入得值可以看到是名稱與日期,所以我需要從 info 資料中取出這兩個資料,使用
push
方法放到 info 陣列中 - 宣告一個 nodeName 放節點名稱。
- 最後把 nodeInfo 的內容換成新組成的值。
- 使用
push
把 nodeInfo 物件依序放入 infoList 的陣列中。
1 | //* 主節點資訊 |
組出未審核的節點資訊
宣告一個空陣列 nodeApplication 存放未審核的節點資訊。
因為我已經知道有部分節點是有資訊的,所以我用
filter
去過濾有節點的資料。在宣告一個 infoList 變數去找出節點資訊如果跟過濾後的節點名稱一樣的時候就回傳 true。
這邊發現如果沒有找到節點就會回傳
undefined
。所以我就判斷當 infoList 是
undefined
的時候,就去組新的資訊內容。最後再把資訊內容
push
到 nodeApplication 陣列中,這樣不管審核流程節點進行到哪裡都會有值。
1 | let nodeApplication: any[] = []; |
合併陣列
最後將已審核跟未審核的節點資訊使用 concat
的方法(這邊使用解構賦值的寫法),去賦值在全域的 info 的陣列中。
concat
1 | this.info = infoList.concat(nodeApplication); |
ES6
1 | this.info = [...infoList, ...nodeApplication]; |
小結
以上就是使用陣列不同的方法整理資料,使用到 forEach
、push
、filter
、find
、concat
以及 ES6 解構賦值的寫法。算是透過此專案練習與更熟悉陣列與物件的操作方法。