1

I try to dynamically step in depth inside an object. The object children is unknown and should instead be used from a string.

I hope you can see below what I try to do. I've comment out the part where I can't figure out a solution.

var global_object = {};

function populate(id, text) {
  let parts = id.split('/');

  for(let key in parts) {
    let part = parts[key];
    // global_object['this']['is']['a']['long']['url'] = text;
    console.log(part);
  }
}

populate('this/is/a/long/url', 'My text');

The results may be something like this:

this: {
  is: {
    a: {
      long: {
        url: "My text"
      }
    }
  }
}

https://jsfiddle.net/2f6kue74/

ES6 solutions are accepted as well

6
  • 2
    Possible duplicate of Javascript: How to create an object from a dot separated string? Commented Feb 6, 2019 at 12:17
  • the answer to your problem is similar if not the same here: by @Tony although what you are doing is considered bad practice. stackoverflow.com/questions/20424226/… Commented Feb 6, 2019 at 12:30
  • @ElieNassif Thanks! Why is it considered bad practice and what is the alternative? Commented Feb 6, 2019 at 12:53
  • @JensTörnell if you rename one of the attributes in another piece of code, the current code will not be functional. Unless you perform a lot of control over it. Not sure what the context of your project is. Commented Feb 6, 2019 at 12:55
  • @ElieNassif I try to generate some kind of file/folder API for fetching files and folders from PHP with ajax. The idea is that when I send an url or id as I call it, it should populate this nested object. Then later I can use that object to render a filetree as html elements from js. Commented Feb 6, 2019 at 13:08

4 Answers 4

1

you can do something like this, store a var obj and put i inside a new key each turn. Then for the text, use another var to "remember" the last one.

var global_object = {};

function populate(id, text) {
  let parts = id.split('/');
  let obj = global_object, last_obj, part;

  for(let key in parts) {
    part = parts[key];
    last_obj = obj;      
    obj[part] = {};
    obj = obj[part]
    console.log(part);
  }
  last_obj[part] = text;
}

populate('this/is/a/long/url', 'My text');
console.log(global_object);

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

Comments

1

An alternative recursive solution self contained with no external variables

const populate = (id, text, result) => {
  const arr = id.split('/');
  let key = arr.shift();
  if(key) { 
    result[key] = {};
    if(!arr.length) { result[key] = text; }
    populate(arr.join("/"), text, result[key])
  }
  return result;
}

console.log(populate('this/is/a/long/url', 'My text', {}));

Comments

0

Something like this should work. obj is the current object to be populated and it is updated with each iteration of the for loop.

let obj = global_object;
function populate(id, text) {
    let parts = id.split('/');

    for (let key in parts) {
        let part = parts[key];
        obj[part] = {};
        obj = obj[part];

    }
    obj = text;
}

Comments

0

Or reduce it

var global_object = {};

function populate(id, text) {
    global_object = id.split("/").reduceRight((acc, part) => {
        var nested = JSON.parse(JSON.stringify(acc));

        acc = {};
        acc[part] = nested;

        return acc;
    }, text);
}

populate("this/is/a/long/url", "My text");

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.