簡體   English   中英

JavaScript:將具有父鍵的對象數組轉換為父/子樹(包括沒有父對象的對象)

[英]JavaScript: Convert array of objects with parent keys to parent / child tree (including objects with no parent)

我有一個帶有父鍵的對象列表,它描述了嵌套父/子關系的幾個級別。

const table =[
    {
        "id": 791,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {
        "id": 790,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {
        "id": 845,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {   
        "id": 844,
        "sortOrder": 0,
        "parentCategoryId": 842
    },
    {   
        "id": 802,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {   
        "id": 788,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 863,
        "sortOrder": 0,
        "parentCategoryId": 863
    },
    {    
        "id": 858,
        "sortOrder": 0,
        "parentCategoryId": 858
    },
    {    
        "id": 867,
        "sortOrder": 0,
        "parentCategoryId": 867
    },
    {    
        "id": 871,
        "sortOrder": 0,
        "parentCategoryId": 867
    },
    {    
        "id": 801,
        "name": "Tickets",
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 792,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 797,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 789,
        "name": "Hot food",
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 798,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 671,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 833,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 796,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 843,
        "sortOrder": 0,
        "parentCategoryId": 842
    },
    {    
        "id": 840,
        "sortOrder": 0,
        "parentCategoryId": 793
    },
    {    
        "id": 868,
        "sortOrder": 0,
        "parentCategoryId": 868
    },
    {    
        "id": 851,
        "sortOrder": 0,
        "parentCategoryId": 851
    },
    {    
        "id": 839,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 793,
        "sortOrder": 0,
        "parentCategoryId": 839
    },
    {    
        "id": 859,
        "sortOrder": 0,
        "parentCategoryId": 859
    },
    {   
        "id": 805,
        "sortOrder": 0,
        "parentCategoryId": 859
    },
    {    
        "id": 856,
        "name": "DRINKS",
        "sortOrder": 0,
        "parentCategoryId": 805
    },
    {    
        "id": 870,
        "sortOrder": 0,
        "parentCategoryId": 856
    },
    {    
        "id": 787,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 786,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 799,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 852,
        "sortOrder": 0,
        "parentCategoryId": 852
    },
    {    
        "id": 795,
        "name": "Gents fragrance",
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 864,
        "sortOrder": 0,
        "parentCategoryId": 864
    },
    {   
        "id": 854,
        "sortOrder": 0,
        "parentCategoryId": 854
    },
    {    
        "id": 865,
        "sortOrder": 0,
        "parentCategoryId": 865
    },
    {    
        "id": 869,
        "name": "GFI",
        "sortOrder": 0,
        "parentCategoryId": 869
    },
    {    
        "id": 785,
        "sortOrder": 0,
        "parentCategoryId": 833
    }
]

問題是我沒有 0 的根父 ID。我想在一個數組中訂購它,該數組顯示在第一級項目中idparentCategoryId匹配,這意味着它們每個都是根,而不是每個都有孩子中的孩子。

這是我走了多遠,但很難做到這一點:

var root = { cid: 0, parent_id: null, children: []};
var node_list = { 0 : root};

     for (var i = 0; i < table.length; i++) {

       console.log('updated list', node_list)
       console.log('item in cat', table[i])

       // check if parent ID exsits in the list
       if (!node_list[table[i].parentCategoryId]) {

         console.log('not in the list');
         console.log('node_list[table[i].parentCategoryId]', table[i].parentCategoryId)
         if (table[i].parentCategoryId === table[i].cid) {
           console.log('it is the root');
           node_list[table[i].cid] = table[i];
         }    

       } else {

         const item = table[i];
         console.log('item is ', item)

         node_list[table[i].parentCategoryId].children = {
           ...node_list[table[i].parentCategoryId].children,
           ...item
         };
       }
     }

預期結果:

const table =[
    {  
        "id": 791,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 790,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 845,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 844,
        "sortOrder": 0,
        "parentCategoryId": 842
    },
    {    
        "id": 802,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 788,
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 863,
        "sortOrder": 0,
        "parentCategoryId": 863
    },
    {    
        "id": 858,
        "sortOrder": 0,
        "parentCategoryId": 858
    },
    {    
        "id": 867,
        "sortOrder": 0,
        "parentCategoryId": 867
    },
    {    
        "id": 871,
        "sortOrder": 0,
        "parentCategoryId": 867
    },
    {    
        "id": 801,
        "sortOrder": 0,
        "parentCategoryId": 847
    },    
    {    
        "id": 797,
        "sortOrder": 0,
        "parentCategoryId": 847,
        children:[
            {    
                "id": 792,
                "sortOrder": 0,
                "parentCategoryId": 797,
                children:[
                    {
                        "id": 671,
                        "sortOrder": 0,
                        "parentCategoryId": 792
                    },
                ]
            },
        ]
    },
    {    
        "id": 789,
        "name": "Hot food",
        "sortOrder": 0,
        "parentCategoryId": 833
    },
    {    
        "id": 798,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {    
        "id": 833,
        "sortOrder": 0,
        "parentCategoryId": 833,
        children:[
            {    
                "id": 785,
                "sortOrder": 0,
                "parentCategoryId": 833
            },
            {
                "id": 786,
                "sortOrder": 0,
                "parentCategoryId": 833
            },
            {
                "id": 787,
                "sortOrder": 0,
                "parentCategoryId": 833
            },
        ]
    },
    {   
        "id": 796,
        "sortOrder": 0,
        "parentCategoryId": 847
    },
    {   
        "id": 843,
        "sortOrder": 0,
        "parentCategoryId": 842
    },
    {   
        "id": 840,
        "sortOrder": 0,
        "parentCategoryId": 793
    },
    {    
        "id": 868,
        "sortOrder": 0,
        "parentCategoryId": 868
    },
    {    
        "id": 851,
        "sortOrder": 0,
        "parentCategoryId": 851
    },
    {    
        "id": 839,
        "sortOrder": 0,
        "parentCategoryId": 847,
        children:[
            {
                "id": 793,
                "sortOrder": 0,
                "parentCategoryId": 839,
                children:[
                    {    
                        "id": 870,
                        "sortOrder": 0,
                        "parentCategoryId": 856
                    },
                ]
            },
        ]
    },
    {    
        "id": 805,
        "sortOrder": 0,
        "parentCategoryId": 859,
        children:[
            {
                "id": 856,
                "sortOrder": 0,
                "parentCategoryId": 805
            },
            {    
                "id": 859,
                "sortOrder": 0,
                "parentCategoryId": 805
            },
        ]
    },      
]

看起來您想向初始數組中的對象添加一個帶有值數組的children鍵,其中id值對應於數組中其他對象的一個​​或多個parentCategoryId值 - 並且不應將任何對象作為父對象或子對象重復在嵌套對象數組中。

您可以map數組以追加子項,然后filter以僅返回根父項(和孤子)。 例如(如果您想查看輸出,請在示例下方的工作片段):

const ids = table.map(x => x.id);

let result = table.map((parent) => {
  let children = table.filter((child) => {
    if (child.id !== child.parentCategoryId && child.parentCategoryId === parent.id) {
      return child;
    }
  });
  if (children.length) {
    parent.children = children;
  }
  return parent;
}).filter((obj) => {
  if (obj.id === obj.parentCategoryId || !ids.includes(obj.parentCategoryId)) {
    // include ultimate parents and orphans at root
    return obj;
  }
});

 const table = [{ "id": 791, "sortOrder": 0, "parentCategoryId": 833 }, { "id": 790, "sortOrder": 0, "parentCategoryId": 833 }, { "id": 845, "sortOrder": 0, "parentCategoryId": 847 }, { "id": 844, "sortOrder": 0, "parentCategoryId": 842 }, { "id": 802, "sortOrder": 0, "parentCategoryId": 847 }, { "id": 788, "sortOrder": 0, "parentCategoryId": 833 }, { "id": 863, "sortOrder": 0, "parentCategoryId": 863 }, { "id": 858, "sortOrder": 0, "parentCategoryId": 858 }, { "id": 867, "sortOrder": 0, "parentCategoryId": 867 }, { "id": 871, "sortOrder": 0, "parentCategoryId": 867 }, { "id": 801, "name": "Tickets", "sortOrder": 0, "parentCategoryId": 847 }, { "id": 792, "sortOrder": 0, "parentCategoryId": 833 }, { "id": 797, "sortOrder": 0, "parentCategoryId": 847 }, { "id": 789, "name": "Hot food", "sortOrder": 0, "parentCategoryId": 833 }, { "id": 798, "sortOrder": 0, "parentCategoryId": 847 }, { "id": 671, "sortOrder": 0, "parentCategoryId": 847 }, { "id": 833, "sortOrder": 0, "parentCategoryId": 833 }, { "id": 796, "sortOrder": 0, "parentCategoryId": 847 }, { "id": 843, "sortOrder": 0, "parentCategoryId": 842 }, { "id": 840, "sortOrder": 0, "parentCategoryId": 793 }, { "id": 868, "sortOrder": 0, "parentCategoryId": 868 }, { "id": 851, "sortOrder": 0, "parentCategoryId": 851 }, { "id": 839, "sortOrder": 0, "parentCategoryId": 847 }, { "id": 793, "sortOrder": 0, "parentCategoryId": 839 }, { "id": 859, "sortOrder": 0, "parentCategoryId": 859 }, { "id": 805, "sortOrder": 0, "parentCategoryId": 859 }, { "id": 856, "name": "DRINKS", "sortOrder": 0, "parentCategoryId": 805 }, { "id": 870, "sortOrder": 0, "parentCategoryId": 856 }, { "id": 787, "sortOrder": 0, "parentCategoryId": 833 }, { "id": 786, "sortOrder": 0, "parentCategoryId": 833 }, { "id": 799, "sortOrder": 0, "parentCategoryId": 847 }, { "id": 852, "sortOrder": 0, "parentCategoryId": 852 }, { "id": 795, "name": "Gents fragrance", "sortOrder": 0, "parentCategoryId": 847 }, { "id": 864, "sortOrder": 0, "parentCategoryId": 864 }, { "id": 854, "sortOrder": 0, "parentCategoryId": 854 }, { "id": 865, "sortOrder": 0, "parentCategoryId": 865 }, { "id": 869, "name": "GFI", "sortOrder": 0, "parentCategoryId": 869 }, { "id": 785, "sortOrder": 0, "parentCategoryId": 833 } ]; const ids = table.map(x => x.id); let result = table.map((parent) => { let children = table.filter((child) => { if (child.id !== child.parentCategoryId && child.parentCategoryId === parent.id) { return child; } }); if (children.length) { parent.children = children; } return parent; }).filter((obj) => { if (obj.id === obj.parentCategoryId || !ids.includes(obj.parentCategoryId)) { // include ultimate parents and orphans at root return obj; } }); // stringify just to flatten out SO console result for easier result scanning console.log(JSON.stringify(result));

我們有一個復雜的 json 文件,我們必須用 JavaScript 處理它以使其具有層次結構,以便以后構建一棵樹。 JSON 數組的每個條目都有 - id - 唯一的 id, parentId - 父節點的 id(如果節點是樹的根,則為 0) level - 樹中的深度級別。

JSON 數據已經“有序”,這意味着條目將在其自身上方具有父節點或兄弟節點,在其自身下方具有子節點或兄弟節點。

 const arr = [   {      "id": "12",      "parentId": "0",      "text": "Man",      "level": "1",      "children": null   },   {      "id": "6",      "parentId": "12",      "text": "Boy",      "level": "2",      "children": null   },   {      "id": "7",      "parentId": "12",      "text": "Other",      "level": "2",      "children": null   },   {      "id": "9",      "parentId": "0",      "text": "Woman",      "level": "1",      "children": null   },   {      "id": "11",      "parentId": "9",      "text": "Girl",      "level": "2",      "children": null   } ]; const listToTree = (arr = []) => {   let map = {}, node, res = [], i;   for (i = 0; i < arr.length; i += 1) {      map[arr[i].id] = i;      arr[i].children = [];   };   for (i = 0; i < arr.length; i += 1) {      node = arr[i];      if (node.parentId !== "0") {         arr[map[node.parentId]].children.push(node);      }      else {         res.push(node);      };   };   return res; }; console.log(JSON.stringify(listToTree(arr), undefined, 4));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM