Sinan Guclu Sinan Guclu - 1 month ago 6
jQuery Question

Use array of strings to create a multi level object, parsing arrays into JS objects

I have this array that needs to be parsed into a useful object. The names of each value are a collection of namespaces separated by / characters. The values between each '/' need to be turned into a JS Objects property:

"status": [
{
"message": "OK",
"name": "/Computer",
"values": []
},
{
"name": "/Computer/CPU Usage",
"values": []
},
{
"name": "/Computer/CPU Temp",
"values": []
},
{
"name": "/Computer/hardware/memory",
"values": []
}
]


I need it to become this:

"status": {
"computer": {
"CPU Usage": {
"values": []
},
"CPU Temp": {
"values": []
},
"hardware": {
"memory": {
"values": []
}
}
}
}


So far I have done this:

var statii = status, // from above..
_parsedStatii = {};

for (var i = 0; statii.length < 0; i ++) {
var _nameSpaces = statii[i].name.split('/');

// Start at 1 because index 0 is empty (before the first slash)
if (!_parsedStatii[_nameSpaces[1]]) {
_parsedStatii[_nameSpaces[1]] = {};
}

if (!_parsedStatii[_nameSpaces[1]][_nameSpaces[2]])
_parsedStatii[_nameSpaces[1]][_nameSpaces[2]] = {};


if (!_parsedStatii[_nameSpaces[1]][_nameSpaces[2]][_nameSpaces[3]])
_parsedStatii[_nameSpaces[1]][_nameSpaces[2]][_nameSpaces[3]] = {};


if (!_parsedStatii[_nameSpaces[1]][_nameSpaces[2]][_nameSpaces[3]][_nameSpaces[4]])
_parsedStatii[_nameSpaces[1]][_nameSpaces[2]][_nameSpaces[3]][_nameSpaces[4]] = {};

}


Obviously it is no where near right, I have tried a lot of recursive functions but am at a bit of a loss. This example gives the clearest representation of what I am trying to achieve. Any ideas? (Please excuse code typos, it was paraphrased)

Answer

You could split the name and build an object upon.

var data = { "status": [{ "message": "OK", "name": "/Computer", "values": [] }, { "name": "/Computer/CPU Usage", "values": [] }, { "name": "/Computer/CPU Temp", "values": [] }, { "name": "/Computer/hardware/memory", "values": [] }] },
    object = {};

data.status.forEach(function (a) {
    a.name.slice(1).split('/').reduce(function (o, k) {
        return o[k] = o[k] || {};
    }, object).values = a.values;
});

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

Comments