Построить дерево из JSON массива объектов - PullRequest
1 голос
/ 25 февраля 2020

Учитывая следующее JSON Array:

    [{"ID":12,"NAME":"ktc","PARENTID":0},
     {"ID":11,"NAME":"root","PARENTID":0}, 
     {"ID":1,"NAME":"rwhitney","PARENTID":0},
     {"ID":21,"NAME":"shared folder","PARENTID":0}, 
     {"ID":2,"NAME":".config","PARENTID":1}, 
     {"ID":5,"NAME":"wallpapers","PARENTID":1}, 
     {"ID":3,"NAME":"geany","PARENTID":2}, 
     {"ID":4,"NAME":"colorschemes","PARENTID":3}, 
     {"ID":13,"NAME":"efast","PARENTID":12}, 
     {"ID":15,"NAME":"includes","PARENTID":13}, 
     {"ID":14,"NAME":"views","PARENTID":13}, 
     {"ID":17,"NAME":"css","PARENTID":15}, 
     {"ID":16,"NAME":"js","PARENTID":15}]

Мне нужно построить дерево меню с подпапками, вложенными в родительские папки.

Вот некоторый код на стороне сервера:

    socket.on('get-folders', function(data){
        var folders = [];
        getSession(session.key, function(currSession){
            db.rows('getFolders', currSession, [currSession.user], function(err, rows){
                if (err) {
                    socket.emit('err', 'Error is: ' + err );
                } else if(rows[0]){
                    //~ folders.push(JSON.stringify(rows));
                    socket.emit('get-folders', JSON.stringify(rows));
                    //~ n_Folders(rows, currSession, socket, folders, 0);
                }
            });
        });
    });

и на стороне клиента:

    function rtnSocket(cmd, data, cb){
        socket.emit(cmd, data);
        socket.on(cmd, cb);
    }

    rtnSocket('get-folders', folderid, function(data){
        console.log(data);
    });

Может кто-нибудь помочь мне направить меня в правильном направлении?

Ответы [ 4 ]

2 голосов
/ 25 февраля 2020

Вы можете собрать все узлы из плоской структуры данных, использовать ID и PARENTID в качестве ключей в таблице ha sh и получить в результате массив root.

var data = [{ ID: 12, NAME: "ktc", PARENTID: 0 }, { ID: 11, NAME: "root", PARENTID: 0 }, { ID: 1, NAME: "rwhitney", PARENTID: 0 }, { ID: 21, NAME: "shared folder", PARENTID: 0 }, { ID: 13, NAME: "efast", PARENTID: 12 }, { ID: 2, NAME: ".config", PARENTID: 1 }, { ID: 5, NAME: "wallpapers", PARENTID: 1 }, { ID: 15, NAME: "includes", PARENTID: 13 }, { ID: 14, NAME: "views", PARENTID: 13 }, { ID: 3, NAME: "geany", PARENTID: 2 }, { ID: 17, NAME: "css", PARENTID: 15 }, { ID: 16, NAME: "js", PARENTID: 15 }, { ID: 4, NAME: "colorschemes", PARENTID: 3 }],
    tree = function (data, root) {
        var t = {};
        data.forEach(o => {
            Object.assign(t[o.ID] = t[o.ID] || {}, o);
            t[o.PARENTID] = t[o.PARENTID] || {};
            t[o.PARENTID].children = t[o.PARENTID].children || [];
            t[o.PARENTID].children.push(t[o.ID]);
        });
        return t[root].children;
    }(data, 0);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 26 февраля 2020

Мне нужно ответить на свой вопрос с помощью Нины выше:

С заданным JSON объектом - ответ от Нины:

[{"ID":12,"NAME":"ktc","PARENTID":0},{"ID":11,"NAME":"root","PARENTID":0},{"ID":1,"NAME":"rwhitney","PARENTID":0},{"ID":21,"NAME":"shared folder","PARENTID":0},{"ID":2,"NAME":".config","PARENTID":1},{"ID":5,"NAME":"wallpapers","PARENTID":1},{"ID":3,"NAME":"geany","PARENTID":2},{"ID":4,"NAME":"colorschemes","PARENTID":3},{"ID":13,"NAME":"efast","PARENTID":12},{"ID":15,"NAME":"includes","PARENTID":13},{"ID":14,"NAME":"views","PARENTID":13},{"ID":17,"NAME":"css","PARENTID":15},{"ID":16,"NAME":"js","PARENTID":15},{"ID":27,"NAME":"images","PARENTID":16}]

Я придумал эту функцию :

image

и вызвать его так:

recurse(data,0,0);

Функция заполняет дерево идентификаторов «папок»

следующим выводом:

enter image description here

Еще раз спасибо за установку меня на правильный путь!

0 голосов
/ 25 февраля 2020

Сначала нам нужно выровнять вложенный массив:

const flatArray = (arr) => {
    return arr.reduce((flat, toFlatten) => {
        return flat.concat(Array.isArray(toFlatten) ? flatArray(toFlatten) : toFlatten);
    }, []);
}

Затем мы можем создать дерево:

const makeTree = dataset => {
    let hashTable = Object.create(null)
    dataset.forEach( aData => hashTable[aData.ID] = { ...aData, childNodes : [] } )
    let dataTree = []
    dataset.forEach( aData => {
      if( aData.PARENTID ) hashTable[aData.PARENTID].childNodes.push(hashTable[aData.ID])
      else dataTree.push(hashTable[aData.ID])
    } )
    return dataTree
}

Пример:

let data = [
    [{ ID: 12, NAME: "ktc", PARENTID: 0 }, { ID: 11, NAME: "root", PARENTID: 0 }, { ID: 1, NAME: "rwhitney", PARENTID: 0 },
    { ID: 21, NAME: "shared folder", PARENTID: 0 }], [{ ID: 13, NAME: "efast", PARENTID: 12 }], [{ ID: 2, NAME: ".config", PARENTID: 1 },
    { ID: 5, NAME: "wallpapers", PARENTID: 1 }], [{ ID: 15, NAME: "includes", PARENTID: 13 }, { ID: 14, NAME: "views", PARENTID: 13 }],
    [{ ID: 3, NAME: "geany", PARENTID: 2 }], [{ ID: 17, NAME: "css", PARENTID: 15 }, { ID: 16, NAME: "js", PARENTID: 15 }],
    [{ ID: 4, NAME: "colorschemes", PARENTID: 3 }]];

const flatArray = (arr) => {
    return arr.reduce((flat, toFlatten) => {
        return flat.concat(Array.isArray(toFlatten) ? flatArray(toFlatten) : toFlatten);
    }, []);
}

const makeTree = dataset => {
    let hashTable = Object.create(null)
    dataset.forEach( aData => hashTable[aData.ID] = { ...aData, childNodes : [] } )
    let dataTree = []
    dataset.forEach( aData => {
      if( aData.PARENTID ) hashTable[aData.PARENTID].childNodes.push(hashTable[aData.ID])
      else dataTree.push(hashTable[aData.ID])
    } )
    return dataTree
}
const dataTree = makeTree(flatArray(data));
console.log(dataTree)
0 голосов
/ 25 февраля 2020

Лучше поместить вложенные папки внутри родительского объекта в виде массива вложенных папок ... это исключит ParentID и упростит переход

[
  {
    "ID": 1,
    "NAME": "rwhitney",
    "PARENTID": 0,
    "SUB": [
      {
        "ID": 2,
        "NAME": ".config",
        "PARENTID": 1,
        "SUB": [
          {
            "ID": 3,
            "NAME": "geany",
            "PARENTID": 2,
            "SUB": [
              {
                "ID": 4,
                "NAME": "colorschemes",
                "PARENTID": 3
              }
            ]
          }
        ]
      },
      {
        "ID": 5,
        "NAME": "wallpapers",
        "PARENTID": 1
      }
    ]
  }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...