0

Though I am programming Javascript several years and at least thought to know the most of it's features and problems, I came across a new one today.

I have an array of device, each device contains a path property. In this path property is also an array.

[
    { // Device object
        path: [1]
        name: "Device 1",...
    },
    { // Device object
        path: [1,3]
        name: "Device 13",...
    },
    { // Device object
        path: [1,3,1]
        name: "Device 131",...
    }...
]

This path property represents the path in an array, I have to create. So the structure above should result in the following (I know it is not valid JS):

[
1 => {
    name: "Device 1",
    children: [
        3 => {
            name: "Device 13",
            children: [
                1 => {
                    name: "Device 131",
                    children: [],...
                },
            ],...
        },
    ],...
},
]

In any other language like e.g. php I would use a reference or a pointer and then looping through the path-array:

$newArr = [];
$ptr = &$newArr;
foreach($path as $key){
    $ptr = &$ptr[$key].children;
}

The only way I can think of doing something like this in JS is by using eval. But maybe you got some better ideas.

To clarify what I want: The first structure should be somehow processed and be "converted to the second structure". The third and last code snippet is the approach I would use in PHP.

Thank You

Luca

3
  • Can you clarify what exactly you want to do? Do you want to create second structure from first one? Commented Aug 3, 2016 at 9:26
  • Are you trying to create such an array/object, or access data in one, or both? Commented Aug 3, 2016 at 9:27
  • I tried to clarify it in the post: The first structure should be somehow processed and be "converted to the second structure". The third and last code snippet is the approach I would use in PHP. Commented Aug 3, 2016 at 9:30

2 Answers 2

1

lets try this (untested):

var tree = new Object();

for(var key in yourFlatArray){
    var path = yourFlatArray[key].path;
    var node = tree;
    while(path.length){
        if(!(path[0] in node)){
            node[path[0]] = new Object();
            node[path[0]]['children'] = new Array();
            node[path[0]]['name'] = yourFlatArray[key].name;
        }
        node = node[path[0]].children;
        path.shift();
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Ok thank you, I actually tried that. Don't know why that didn't work, but I rewrote it and now it is working.
Glad to help you :) Could you post the working version please.
If you used an object to represent the tree, I think you should do the same with the children array. Also, shifting will destroy the original paths.
0

You can use reduce by passing the current nested level of results object and the id (property key) of the path. Whenever a device entry does not exist, it is added to the current object.

var result = {};
devices.forEach(function(device){

    device.path.reduce(function(obj, id){
        if( !obj.hasOwnProperty(id) )
            obj[id] = { name: device.name, children: {} };
        return obj[id].children;
    }, result);

});

var devices = [{
  path: [1],
  name: "Device 1"
},{
  path: [1, 2],
  name: "Device 12"
},{
  path: [1, 3],
  name: "Device 13"
},{
  path: [1, 3, 1],
  name: "Device 131"
}];


var result = {};
devices.forEach(function(device) {

  device.path.reduce(function(obj, id) {
    if (!obj.hasOwnProperty(id))
      obj[id] = {
        name: device.name,
        children: {}
      };
    return obj[id].children;
  }, result);

});
console.log(result);

Comments

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.