1

I wanna create a nested object dynamically. I can create it hard coded. Is it possible to do this with a loop ?

result = {}
keys = ["a", "b", "c", "d"]

result[keys[0]] = {}
result[keys[0]][keys[1]] = {}
result[keys[0]][keys[1]][keys[2]] = {}
result[keys[0]][keys[1]][keys[2]][keys[3]] = "cool"

I want to pass an integer for example if it is "3", this should created an object like:

result = {
  "a": {
     "b": {
        "c": "cool"
     }
   }
}

If it is 4, :

result = {
  "a": {
     "b": {
        "c": {
           "d": "cool"
        }
     }
   }
}

So on ...

edit:

I am also checking result object, in order to create this nested structure. If there is not any field yet, I simply create the object.

Using this structure to group data. Any chance to check these dynamically ?

if (!result[keys[0]]) 
if (!result[keys[0]][keys[1]]) 
if (!result[keys[0]][keys[1]][keys[2]]) 
5
  • will keys contain the correct number of input (what if the input is 5)? Commented Jul 10, 2019 at 15:59
  • 1
    You could do it using recursion and map the index of the iteration with its alphabetical representation. Commented Jul 10, 2019 at 16:01
  • @depperm Getting keys as a param of this function. It might change in the future. This is why ı am looking for dynamic solution. You can basically use keys.length in order to determine. Commented Jul 10, 2019 at 16:01
  • what problem you have? do you asking how to use for-loop in javascript? Commented Jul 10, 2019 at 16:02
  • @appleapple yes, Commented Jul 10, 2019 at 16:03

5 Answers 5

6

You can use reduceRight() for this. It just starts from the inside at the last item in the keys list and works its way out starting with "cool":

let keys = ["a", "b", "c", "d"]
let limit = 3

let result = keys.reduceRight((obj, key) => ({[key]: obj}), "cool")

console.log(result)

To limit where the object stops you can iterate over a slice of the keys. For example:

let keys = ["a", "b", "c", "d"]
let start = 0
let stop = 3 // slices are don't inlcude the last item, so this will stop at index 2

let result = keys.slice(start, stop).reduceRight((obj, key) => ({
  [key]: obj
}), "cool")

console.log(result)

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

7 Comments

OP say's he wants to pass an integer, so maybe your keys could be -> Array(3).fill().map((f, ix) => String.fromCharCode(97 + ix)).reduceRight(.... etc
There's a reduceRight function?! Oh well, time to do some refactoring. "I want to pass an integer for example if it is "3", this should created an object like [object three levels deep]." Might need to add a slice before the reduce
Perfect ! Any chance to use that between in range. Like start with index 1 ("b") and ends with index 2 ("c")
Thanks @Keith, I missed that part.
@MarkMeyer Amazing, you’re a great help ! Thank you so much.
|
1

If you like to add to a given object a new property, you could reduce the keys with the object and take default objects for not given keys. At the end assign the value.

function setValue(object, path, value, limit) {
    var keys = path.slice(0, limit),
        last = keys.pop();

    keys.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
    return object;
}

var result = { foo: 42 },
    keys = ["a", "b", "c", "d"];

setValue(result, keys, 'cool');
console.log(result);

setValue(result, keys, 'cool', 3);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

1

short and simple using reduce

let object1= {}
keys = ['a', 'b', 'c']

keys.reduce((prev,curr,i)=>{
    prev[curr] = {}
    return prev[curr]
}, object1)

log(object1) 
// {
//   a:{
//     b:{
//        c:{}
//     }
//   }
// }

Comments

0

simple for-loop solution.

let result = {}
let keys = ["a", "b", "c", "d"]
let depth=3;

let current = result
for(let i=0;i<depth;++i){
  let key = keys[i]
  if(i == depth-1) current[key] = 'cool'
  else current = current[key] = {}

}

console.log(result)

Comments

-1

I'd use a reducer, along with some basic tests to help me out: https://youtu.be/D6zLI8zrfVs

enter image description here

https://gist.github.com/brianswisher/2ce1ffe3ec08634f78aacd1b7baa31f9

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.