0

I have an array of string, I want to convert to nested object where key is value of array. I've try with reduce, but all of the value nested with the last object is last item from the array. Can you help me? Thanks!

let m = [
  '1.',
  '1.1.',
  '1.2.',
  '1.3.',
  '1.4.',
  '1.1.1.',
  '1.1.2.',
  '1.1.3.',
  '1.2.1.',
  '1.2.2.',
  '1.3.1.',
  '1.3.2.',
  '1.3.3.',
  '1.3.4.',
  '1.4.1.',
  '1.4.3.',
];

I want to convert this array to nested object.

Return

  {
    "1":{
        "1":{
            "1":"1.1.1.", 
            "2":"1.1.2.", 
            "3":"1.1.3."
        }, 
        "2":{
            "1":"1.2.1.", 
            "2":"1.2.2."
        }, 
        "3":{
            "1":"1.3.1.", 
            "2":"1.3.2.", 
            "4":"1.3.4."
        }, 
        "4":{
            "1":"1.4.1.", 
            "3":"1.4.3."
        }
     }
    }
lamboktulus1379
  • 350
  • 1
  • 4
  • 10
  • 2
    I suggest you try to adapt something here https://stackoverflow.com/questions/28058519/javascript-convert-dot-delimited-strings-to-nested-object-value – Marc Nov 12 '20 at 04:24

1 Answers1

2

Here's a working example using reduce().

let m = [
  '1.',
  '1.1.',
  '1.2.',
  '1.3.',
  '1.4.',
  '1.1.1.',
  '1.1.2.',
  '1.1.3.',
  '1.2.1.',
  '1.2.2.',
  '1.3.1.',
  '1.3.2.',
  '1.3.3.',
  '1.3.4.',
  '1.4.1.',
  '1.4.3.',
];

const addToObj = (obj_, path, newData) => {
  const obj = typeof obj_ === 'string' ? {} : obj_ // Special logic to cause a value at 1.2.3. to override a value at 1.2.
  if (path.length === 0) return newData
  const [head, ...tail] = path
  return {
    ...obj,
    [head]: addToObj(obj[head] || {}, tail, newData),
  }
}

const res = m.reduce(
  (obj, path) => addToObj(obj, path.split('.').slice(0, -1), path),
  {}
)

console.log(res)

It works by using a addToObj function, that'll take an object as a parameter, a path into that object, and a new value wanted at the end of that path, and it'll return a new object with the new value added.

Special logic was added to addToObj() to make sure keys like 1.2.3. always overwrote a string value that might have been placed at 1.2..

Scotty Jamison
  • 10,498
  • 2
  • 24
  • 30