2

I have got a . (dot) separated string, from which I want to create nested JSON object. The length of the string is not fixed. For example,

var string = 'a.b.c.d';

Then my JSON object should be as following:

a: {
    b: {
        c:{
           d: {
                  //Some properties here. 
              }
          } 
    }
}

I've tried following code:

var packageName = "a.b.c.d"
var splitted = packageName.split('.');
var json = {};
for(var i=0;i<splitted.length-1;i++){
    json[splitted[i]] = splitted[i+1];
}

But this returns

{
    a: 'b', 
    b: 'c',
    c: 'd'
}

But this is not what I want. I've also searched on google and found similar questions, but no solutions answer my problem. For example this.

1
  • You're asking how to create a nested JS object, not JSON. To create JSON would be to create your JS object, and then serialize it to the JSON text format. Commented Mar 9, 2018 at 16:55

3 Answers 3

3

A good use case for reduce

packageName = "a.b.c.d";
initProps = {hi: 'there'};

obj = packageName.split('.').reduceRight((o, x) => ({[x]: o}), initProps);

console.log(JSON.stringify(obj))

If you find loops easier to work with, a loop could be written concisely as

result = {};
ptr = result;

for (let prop of packageName.split('.'))
    ptr = ptr[prop] = {};
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for alternative. But it's quite difficult for me to understand this. +1.
Excellent use case for reduce[Right]. So many nasty and incomprehensible examples of functional programming get posted here, especially with reduce, it's nice to see clean, clear, idiomatic examples.
1

You need to create a new object each time and attribute it to the last object created. And it goes until splitted.length, not splitted.length - 1, because you're using <, not <=.

var packageName = "a.b.c.d";
var splitted = packageName.split('.');
var json = {};
var current = json;
for (var i = 0; i < splitted.length; i++) {
    current[splitted[i]] = {};
    current = current[splitted[i]];
}
console.log(json);

1 Comment

correct! I didn't just think of this simple logic. Thanks . +1 and accept!
0

You may use the last splittted part as property for some payload.

I suggest to keep the object reference and use a temporary variable for aceessing an creating a new property, if necessary.

Please avoid the use of JSON for not stringified objects.

var packageName = "a.b.c.d",
    splitted = packageName.split('.'),
    result = {},
    temp = result,
    i;
  
for (i = 0; i < splitted.length - 1; i++) {
   temp[splitted[i]] = temp[splitted[i]] || {};
   temp = temp[splitted[i]];
}

temp[splitted[i]] = { some: 'data' };

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.