Вложенный массив объектов по уровню иерархии javascript / typescript

У меня есть набор данных, подобный приведенному ниже:

dataSet = {rows: [
    {"ID":0, "Value":10, "HIERARCHY_LEVEL":1},
    {"ID":1, "Value":20, "HIERARCHY_LEVEL":2},
    {"ID":2, "Value":55, "HIERARCHY_LEVEL":3},
    {"ID":3, "Value":77, "HIERARCHY_LEVEL":2},
    {"ID":4, "Value":29, "HIERARCHY_LEVEL":3},
    {"ID":5, "Value":44, "HIERARCHY_LEVEL":4},
    {"ID":6, "Value":34, "HIERARCHY_LEVEL":5},
    {"ID":7, "Value":56, "HIERARCHY_LEVEL":4},
    {"ID":8, "Value":23, "HIERARCHY_LEVEL":2},
    {"ID":9, "Value":23, "HIERARCHY_LEVEL":3},
    {"ID":10, "Value":23, "HIERARCHY_LEVEL":1},
    {"ID":11, "Value":23, "HIERARCHY_LEVEL":2},
    {"ID":12, "Value":23, "HIERARCHY_LEVEL":2},
    {"ID":13, "Value":23, "HIERARCHY_LEVEL":3},
]}

Я хотел бы переупорядочить этот набор данных по уровню иерархии, чтобы каждый уровень помещался в массив свойств children предыдущего объекта, как показано ниже:

NOTE: The dataSet is loaded in, as is (in-order). Also, it does not matter if all objects have the children property.

(Я попытался отформатировать его для удобства чтения)

newDataSet = [
    {"ID":0, "Value":10, "HIERARCHY_LEVEL":1, "children":[
        {"ID":1, "Value":20, "HIERARCHY_LEVEL":2, "children":[
            {"ID":2, "Value":55, "HIERARCHY_LEVEL":3}
        ]},
        {"ID":3, "Value":77, "HIERARCHY_LEVEL":2, "children":[
            {"ID":4, "Value":29, "HIERARCHY_LEVEL":3, "children":[
                {"ID":5, "Value":44, "HIERARCHY_LEVEL":4, "children":[
                    {"ID":6, "Value":34, "HIERARCHY_LEVEL":5}
                ]},
                {"ID":7, "Value":56, "HIERARCHY_LEVEL":4}
            ]}
        ]},
        {"ID":8, "Value":23, "HIERARCHY_LEVEL":2, "children":[
            {"ID":9, "Value":23, "HIERARCHY_LEVEL":3}
        ]}
    ]},
    {"ID":10, "Value":23, "HIERARCHY_LEVEL":1, "children":[
        {"ID":11, "Value":23, "HIERARCHY_LEVEL":2},
        {"ID":12, "Value":23, "HIERARCHY_LEVEL":2, "children":[
            {"ID":13, "Value":23, "HIERARCHY_LEVEL":3}
        ]}
    ]}
]

Редактировать

Мой текущий код

let newResults = [];
let topHierarchyLevel = 1;
let resultCounter = (newResults.length - 1); //Get the 2nd last element of newResults
let currentLevel = 2;
let loopCounter = 0;
for (loopCounter; loopCounter < dataSet.rows.length; loopCounter++) {
    let row = dataSet.rows[loopCounter];
    row["children"] = [];
    if (row.HIERARCHY_LEVEL == topHierarchyLevel) {
        newResults.push(row);
        resultCounter++;
    } else {
        if (row.HIERARCHY_LEVEL == 2) {
            newResults[resultCounter].children.push(row);
            currentLevel++;
        } else if (row.HIERARCHY_LEVEL > 2) {
            newResults[resultCounter-1].children.children.push(row);
            currentLevel++;
            resultCounter++;
        } else {
            currentLevel--;
            resultCounter--;
            loopCounter--;
        }
    }
}

...у вас есть вопрос? SO - это не сервис для написания кода.

jonrsharpe 11.04.2018 13:44

@jonrsharpe Как бы вы перебирали каждый уровень и добавляли его к соответствующему уровню иерархии?

Stefan 11.04.2018 13:45

И на какой именно части вы застряли? Вы знаете, например, как перебирать массив? В противном случае вводное руководство было бы более подходящим, чем вопрос SO. Пожалуйста, дайте минимальный воспроизводимый пример, показывающее, что вы пробовали и где именно вы должны.

jonrsharpe 11.04.2018 13:47

Да, я могу перебрать массив и найти, в какой иерархии я сейчас нахожусь. Однако я не могу добавить строку во вложенное свойство children по мере того, как уровни продолжаются.

Stefan 11.04.2018 13:50
0
4
314
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать свойство уровня HIERARCHY_LEVEL для указания вложенной позиции во вспомогательном массиве.

Затем выполните итерацию данных и при необходимости создайте дочерние массивы.

function getTree(array) {
    var levels = [{}];
    array.forEach(function (o) {
        levels.length = o.HIERARCHY_LEVEL;
        levels[o.HIERARCHY_LEVEL - 1].children = levels[o.HIERARCHY_LEVEL - 1].children || [];
        levels[o.HIERARCHY_LEVEL - 1].children.push(o);
        levels[o.HIERARCHY_LEVEL] = o;
    });
    return levels[0].children;
}

var data = [{ ID: 0, Value: 10, HIERARCHY_LEVEL: 1 }, { ID: 1, Value: 20, HIERARCHY_LEVEL: 2 }, { ID: 2, Value: 55, HIERARCHY_LEVEL: 3 }, { ID: 3, Value: 77, HIERARCHY_LEVEL: 2 }, { ID: 4, Value: 29, HIERARCHY_LEVEL: 3 }, { ID: 5, Value: 44, HIERARCHY_LEVEL: 4 }, { ID: 6, Value: 34, HIERARCHY_LEVEL: 5 }, { ID: 7, Value: 56, HIERARCHY_LEVEL: 4 }, { ID: 8, Value: 23, HIERARCHY_LEVEL: 2 }, { ID: 9, Value: 23, HIERARCHY_LEVEL: 3 }, { ID: 10, Value: 23, HIERARCHY_LEVEL: 1 }, { ID: 11, Value: 23, HIERARCHY_LEVEL: 2 }, { ID: 12, Value: 23, HIERARCHY_LEVEL: 2 }, { ID: 13, Value: 23, HIERARCHY_LEVEL: 3 }];

console.log(getTree(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Спасибо за ответ. Вопрос: Почему параметр level передается в функции getTree, поскольку я считаю, что он не используется? Кроме того, когда я пытаюсь запустить это, я получаю сообщение об ошибке Свойство children не существует для типа "{}", вы знаете, почему?

Stefan 11.04.2018 15:17

параметр остался после попытки использовать переменную для ключа уровня. другая проблема не должна возникать с уровнями, начинающимися с одного, и на всех уровнях нет дыр, например, уровень 5 следует за уровнем 3, без уровня 4.

Nina Scholz 11.04.2018 15:22

Другие вопросы по теме