1

I have an array with increasing specificity eg.

const locationProperties = ['earth', 'americas', 'canada', 'saskatchewan'];

and I would like an object:

{
 earth: {
  americas: {
   canada: {
    saskatchewan: {
      // data 
    }
   }  
  }
 }
}

I was thinking to use .reduce to create the object but after applying the transformation in the reducer I am only left with {}

const reducer = (accumulator, item) => {
  accumulator[item] = {};
  return accumulator[item];
}

const reducedArray = locationProperties.reduce(reducer, {});

1 Answer 1

4

I would recommend a simple recursion function, nest -

const nest = ([key, ...more], val) =>
  key == null
    ? val
    : {[key]: nest(more, val)}
    
const loc =
  ['earth', 'americas', 'canada', 'saskatchewan']    

console.log(nest(loc, "something"))

{
  "earth": {
    "americas": {
      "canada": {
        "saskatchewan": "something"
      }
    }
  }
}

You can also use reduceRight -

const loc =
  ['earth', 'americas', 'canada', 'saskatchewan']    

const result =
  loc.reduceRight((val, key) => ({[key]: val}), "something")

console.log(result)

{
  "earth": {
    "americas": {
      "canada": {
        "saskatchewan": "something"
      }
    }
  }
}

Since you are familiar with reduce I will point out that arr.reduceRight(...) is the effectively the equivalent of arr.reverse().reduce(...). However using reduceRight is more efficient in this case and will not mutate the input array -

const loc =
  ['earth', 'americas', 'canada', 'saskatchewan']    

const result =
  loc.reverse().reduce((val, key) => ({[key]: val}), "something")

console.log(result)

{
  "earth": {
    "americas": {
      "canada": {
        "saskatchewan": "something"
      }
    }
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Wow. This is beautiful. I like this solution a lot. I also tried to solve this question, but mine isn't as beautiful as yours. I think it will be more perfect if you change the argument "something" to {}?
Thanks for the comment, Miu. I really appreciate it. I made the inner var "something" to signal that it can be whatever the caller wants. Also I didn't want people to get confused thinking {} was the beginning of the outermost object.
I got it :) Thank you for your kind reply. Now I fully agree with you and "something" :)

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.