0

I have a dataset similar to the one below:

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},
]}

I would like to re-arrange this dataSet by the hierarchy level, so each level is put into a children property array of the previous object like below:

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

(I have tried to format it for easier reading)

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}
        ]}
    ]}
]

Edit

My current code

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--;
        }
    }
}
4
  • 1
    ...do you have a question? SO isn't a code-writing service. Commented Apr 11, 2018 at 11:44
  • @jonrsharpe How would you iterate through each level and add it to it's corresponding hierarchy level? Commented Apr 11, 2018 at 11:45
  • 1
    And which part of that exactly are you stuck on? Do you know how to iterate over the array, for example? If not, an introductory tutorial would be more appropriate than an SO question. Please give a minimal reproducible example showing what you've tried and where precisely you've got to. Commented Apr 11, 2018 at 11:47
  • Yes i'm able to iterate over the array and find which hierarchy i'm currently on. However, i'm not able to add the row to the nested children property as the levels go on Commented Apr 11, 2018 at 11:50

1 Answer 1

2

You could use the level property HIERARCHY_LEVEL for indicating the nested position in a helper array.

Then iterate the data and build children arrays, if necessary.

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; }

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the response. Question: Why is the parameter level passed though on the getTree function as I believe it's not being used? Also, when I try to run this, I get the error Property children does not exist on type '{}', do you know why?
the parameter was leftover of a try to use a variable for the key of level. the other problem shoud not occur with levels starting with one and all levels have no holes, like level 5 follows after level 3, without level 4.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.