0

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:

  • Strings stored in the str array will not be sorted and the code should be robust against that.
  • Strings will follow the x.y.x.y... pattern, where x will be unique for that array and y can change. In my example country and level will always be the same as they represent the x pos.
  • This requires recursive approach as the strings stored in the str array, can be of any length. The longer the string the deeper nesting.
3
  • JSON (JavaScriptObjectNotation) is JavaScript. But JavaScript is not JSON. Commented Aug 27, 2015 at 12:12
  • @DavidVollmers Neither is the other. There are similarities, but one is a scripting language and the other is a data serialisation format. Commented Aug 27, 2015 at 12:14
  • I welcome your critique, I'm not an expert at this, and if you find something is not accurate, it would be nice if you've edited my question. Thank you. Commented Aug 27, 2015 at 12:19

2 Answers 2

1

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.

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

4 Comments

forEach call requires IE9+
@px5x2 - And? Whats the problem with that? The OP said nothing about IE < 9. And re-writing the code without a forEach will take about 30 seconds.
From reading Eloquent JavaScript I learnt that forEach is much slower than an old-school for loop, with deep nesting as well.
@AmirPopovich nothing wrong, just wanted to state. Like we all write code completely unaware of browser compatibility.
1

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>');

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.