Строительное дерево из JSON данных - PullRequest
1 голос
/ 10 марта 2020

Я пытаюсь построить JSON древовидную структуру, которая рекурсивно вкладывает каждый элемент, в настоящее время у меня есть это:

var data = [
    {
       "id":"",
       "items":[
          {
             "fullName":"images",
             "name":"images",
             "type":"folder",
             "dateCreated":1578270119240,
             "updatedDate":1583448360597
          },
          {
             "fullName":"media",
             "name":"media",
             "type":"folder",
             "dateCreated":1578270119445,
             "updatedDate":1583383567345
          }
       ]
    },
    {
       "id":"images",
       "items":[
          {
             "fullName":"images/123123",
             "name":"123123",
             "type":"folder",
             "dateCreated":1578270119244,
             "updatedDate":1583384536404
          },
          {
             "fullName":"images/banners",
             "name":"banners",
             "type":"folder",
             "dateCreated":1578270119257,
             "updatedDate":1583384536407
          },
          {
             "fullName":"images/doodle",
             "name":"doodle",
             "type":"folder",
             "dateCreated":1578270119441,
             "updatedDate":1583384536421
          }
       ]
    },
    {
        "id":"media",
        "items":[
           {
              "fullName":"media/123123",
              "name":"123123",
              "type":"folder",
              "dateCreated":1578270119244,
              "updatedDate":1583384536404
           },
           {
              "fullName":"media/banners",
              "name":"banners",
              "type":"folder",
              "dateCreated":1578270119257,
              "updatedDate":1583384536407
           },
           {
              "fullName":"media/doodle",
              "name":"doodle",
              "type":"folder",
              "dateCreated":1578270119441,
              "updatedDate":1583384536421
           }
        ]
     },
     {
        "id":"media/123123",
        "items":[
           {
              "fullName":"media/123123/1000",
              "name":"1000",
              "type":"folder",
              "dateCreated":1578270119244,
              "updatedDate":1583384536404
           }
        ]
     }
 ];

console.log( buildHierarchy(data) );

function buildHierarchy(arry) {

var roots = [], items = {};

for(var i = 0, len = arry.length ; i < len; i++) {
    var item = arry[i],
    p = item.id;
    target = !p ? roots : (items[p] || (items[p] = []));
    target.push({id : item.id,
        items : item.items
        })
}


var findChildren = function(parent) {
        for (var j = 0, len = parent.items.length; j < len; j++) {
            if(items[parent.items[j].fullName]) {
                parent.items[j].items = items[parent.items[j].fullName];
                //console.log(parent.items[j].items);
                findChildren(parent.items[j]);
                
            }
        }
    
}

for (var i = 0, len = roots.length; i < len; i++) {
    findChildren(roots[i])
}

return roots;
}

Он вкладывает большую часть данных, но, похоже, пропускает один из узлов, которые я sh создаю, я не могу понять, что я должен вызывать рекурсивно, чтобы все узлы созданы. Я sh для отображения данных так:

[
   {
      "id":"",
      "items":[
         {
            "id":"images",
            "fullName":"images",
            "name":"images",
            "type":"folder",
            "dateCreated":1578270119240,
            "updatedDate":1583448360597,
            "items":[
               {
                  "id":"images/123123",
                  "fullName":"images/123123",
                  "name":"123123",
                  "type":"folder",
                  "dateCreated":1578270119244,
                  "updatedDate":1583384536404,
                  "items":[

                  ]
               },
               {
                  "id":"images/banners",
                  "fullName":"images/banners",
                  "name":"banners",
                  "type":"folder",
                  "dateCreated":1578270119257,
                  "updatedDate":1583384536407,
                  "items":[

                  ]
               },
               {
                  "id":"images/doodle",
                  "fullName":"images/doodle",
                  "name":"doodle",
                  "type":"folder",
                  "dateCreated":1578270119441,
                  "updatedDate":1583384536421,
                  "items":[

                  ]
               }
            ]
         },
         {
            "id":"media",
            "fullName":"media",
            "name":"media",
            "type":"folder",
            "dateCreated":1578270119445,
            "updatedDate":1583383567345,
            "items":[
               {
                  "fullName":"media/123123",
                  "name":"123123",
                  "type":"folder",
                  "dateCreated":1578270119244,
                  "updatedDate":1583384536404,
                  "items":[
                     {
                        "id":"media/123123",
                        "items":[
                           {
                              "fullName":"media/123123/1000",
                              "name":"1000",
                              "type":"folder",
                              "dateCreated":1578270119244,
                              "updatedDate":1583384536404
                           }
                        ]
                     }
                  ]
               }
            ]
         }
      ]

1 Ответ

1 голос
/ 10 марта 2020

Самый простой подход - создать рекурсивную функцию, начиная с "id": "". Затем вы можете вывести sh из каждого узла элемента с полными метаданными, найденными в массиве данных. Если функция рекурсивная и имеет соответствующие проверки остановки, то вы должны быть в состоянии следовать дереву сколь угодно глубоко.

Единственным недостатком является то, что если у вас есть "id": "foo" без соответствующего "name": "foo" в root узел, тогда он останется вне вашего дерева. Я собираюсь предположить, что это невозможно, но об этом нужно знать.

function findNode(id){
  return data.find(e => e.id === id);
}

function buildHierarchy(node) {
  if (!node) return;
  const items = node.items || [];
  for (item of items) {
    // Append the information in the item with the
    // corresponding node in the data array, including
    // the item's items array. This is the recursive
    // part. We keep walking down the tree until we
    // can't find an item's "full info node" in the
    // data array.
    const fullInfoNode = findNode(item.fullName);
    Object.assign(item, buildHierarchy(fullInfoNode));
  }
  return node;
}

buildHierarchy(findNode(""))

function findNode(id){
  return data.find(e => e.id === id);
}

function buildHierarchy(node) {
  if (!node) return;
  const items = node.items || [];
  for (item of items) {
    const fullInfoNode = findNode(item.fullName);
    Object.assign(item, buildHierarchy(fullInfoNode));
  }
  return node;
}

var data = [
    {
       "id":"",
       "items":[
          {
             "fullName":"images",
             "name":"images",
             "type":"folder",
             "dateCreated":1578270119240,
             "updatedDate":1583448360597
          },
          {
             "fullName":"media",
             "name":"media",
             "type":"folder",
             "dateCreated":1578270119445,
             "updatedDate":1583383567345
          }
       ]
    },
    {
       "id":"images",
       "items":[
          {
             "fullName":"images/123123",
             "name":"123123",
             "type":"folder",
             "dateCreated":1578270119244,
             "updatedDate":1583384536404
          },
          {
             "fullName":"images/banners",
             "name":"banners",
             "type":"folder",
             "dateCreated":1578270119257,
             "updatedDate":1583384536407
          },
          {
             "fullName":"images/doodle",
             "name":"doodle",
             "type":"folder",
             "dateCreated":1578270119441,
             "updatedDate":1583384536421
          }
       ]
    },
    {
        "id":"media",
        "items":[
           {
              "fullName":"media/123123",
              "name":"123123",
              "type":"folder",
              "dateCreated":1578270119244,
              "updatedDate":1583384536404
           },
           {
              "fullName":"media/banners",
              "name":"banners",
              "type":"folder",
              "dateCreated":1578270119257,
              "updatedDate":1583384536407
           },
           {
              "fullName":"media/doodle",
              "name":"doodle",
              "type":"folder",
              "dateCreated":1578270119441,
              "updatedDate":1583384536421
           }
        ]
     },
     {
        "id":"media/123123",
        "items":[
           {
              "fullName":"media/123123/1000",
              "name":"1000",
              "type":"folder",
              "dateCreated":1578270119244,
              "updatedDate":1583384536404
           }
        ]
     }
 ];
 
console.log( buildHierarchy(findNode("")) );

Обратите внимание, что при таком подходе вы можете выбрать любой начальный узел, какой захотите. Например, buildHierarchy(findNode("media")) вернет только медиа-иерархию:

{
  "id": "media",
  "items": [
    {
      "fullName": "media/123123",
      "name": "123123",
      "type": "folder",
      "dateCreated": 1578270119244,
      "updatedDate": 1583384536404,
      "id": "media/123123",
      "items": [
        {
          "fullName": "media/123123/1000",
          "name": "1000",
          "type": "folder",
          "dateCreated": 1578270119244,
          "updatedDate": 1583384536404
        }
      ]
    },
    {
      "fullName": "media/banners",
      "name": "banners",
      "type": "folder",
      "dateCreated": 1578270119257,
      "updatedDate": 1583384536407
    },
    {
      "fullName": "media/doodle",
      "name": "doodle",
      "type": "folder",
      "dateCreated": 1578270119441,
      "updatedDate": 1583384536421
    }
  ]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...