Mantas
Mantas

Reputation: 3239

Recursive string parsing into object

Hello guys I'm trying to parse an array of strings into a custom structure:

var str = [
"country.UK.level.1",
"country.UK.level.2",
"country.US.level.1",
"country.UK.level.3"
];

Into something like:

var ordered = {
   "country": [
      {"UK" : {"level" : ["1", "2", "3"]}},
      {"US" : {"level" : ["1","2"]}}
   ]
}

Notes:

Upvotes: 0

Views: 661

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386654

This solution utilized a Array.prototype.forEach and Array.prototype.reduce.

var str = [
        "country.UK.level.1",
        "country.UK.level.2",
        "country.US.level.1",
        "country.UK.level.3"
    ],
    ordered = {};

str.forEach(function (a) {
    var aa = a.split('.'),
        val = aa.pop(),
        last = aa.length - 1;

    aa.reduce(function (obj, pro, i) {
        if (!(pro in obj)) {
            obj[pro] = i === last ? [] : {};
        }
        return obj[pro];
    }, ordered).push(val);
});
document.write('<pre>' + JSON.stringify(ordered, 0, 4) + '</pre>');

Upvotes: 1

Amir Popovich
Amir Popovich

Reputation: 29836

This should work for you if the last level of your object is an array:

var str = [
"country.UK.level.1",
"country.UK.level.2",
"country.US.level.1",
"country.UK.level.3"
];

var obj = {};

str.forEach(function(str){
    var curr = obj;
    var splitted = str.split('.');
    var last = splitted.pop();
    var beforeLast = splitted.pop();

    splitted.forEach(function(sub){
        if(!curr.hasOwnProperty(sub))
        {
            curr[sub] = {};
        }

        curr = curr[sub];
    });

    if(!curr[beforeLast]){
        curr[beforeLast] = [];
    }
    curr[beforeLast].push(last);
})

console.log(obj);

JSFIDDLE.

Upvotes: 1

Related Questions