-4

I have an array of object:

arrayOfObjects = [
                    {
                    "name": "A",
                    "child": [
                        {
                        "name": "A1",
                        "child": [
                            {
                            "name": "A1a"
                            },
                            {
                            "name": "A1b"
                            },
                            {
                            "name": "A1c"
                            }
                        ]
                        },
                        {
                        "name": "A2",
                        "child": [
                            {
                            "name": "A2a"
                            },
                            {
                            "name": "A2b"
                            }
                        ]
                        },
                        {
                        "name": "A3",
                        "child": [
                            {
                            "name": "A3a"
                            },
                            {
                            "name": "A3b"
                            },
                            {
                            "name": "A3c"
                            },
                            {
                            "name": "A3d"
                            }
                        ]
                        },
                        {
                        "name": "A4",
                        "child": [
                            {
                            "name": "A4a"
                            },
                            {
                            "name": "A4b"
                            },
                            {
                            "name": "A4c"
                            }
                        ]
                        }
                    ]
                    },
                    {
                    "name": "B",
                    "child": [
                        {
                        "name": "B1",
                        "child": [
                            {
                            "name": "B1a"
                            },
                            {
                            "name": "B1b"
                            }
                        ]
                        },
                        {
                        "name": "B2",
                        "child": [
                            {
                            "name": "B2a"
                            },
                            {
                            "name": "B2b"
                            }
                        ]
                        },
                        {
                        "name": "B3",
                        "child": [
                            {
                            "name": "B3A"
                            },
                            {
                            "name": "B3b"
                            },
                            {
                            "name": "B3c"
                            },
                            {
                            "name": "B3d"
                            },
                            {
                            "name": "B3e"
                            }
                        ]
                        }
                    ]
                    },
                    {others objects with same structure}
                ]

I need to create an array of arrays from this array of object with this structure :

 array = [[A,A1,A1a],
               [A1b],
               [A1c],
            [A2,A2a],
               [A2b],
            [A3,A3a],
               [A3b],
               [A3c],
               [A3d],
            [A4,A4a],
               [A4b],
               [A4c],
          [B,B1,B1a] 
                and so on]

The purpose is to writ a line for each array in a Google spreadsheet.

I'm getting lost with the forEach method, in each object, the child key contains other arrays of object having child themselves, I don't know how to iterate in this hierarchy

mthgn
  • 77
  • 9
  • 3
    This looks like you should be using recursion. – Barmar Apr 06 '23 at 21:41
  • are you talking about something like this ? `function walkTree(node) { if (node === null) {return;} // do something with node for (let i = 0; i < node.childNodes.length; i++) { walkTree(node.childNodes[i]); } } ` found [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#recursion) – mthgn Apr 06 '23 at 21:49

2 Answers2

-1

You can achieve this using self-contained recursion (not relying on a global accumulator or passed context) by distributing the results of the deepest recursive calls across each level on the way back up. Here using a nested for...of loop on the results of the recursive call.

const arrayOfObjects = [{ name: 'A', child: [{ name: 'A1', child: [{ name: 'A1a' }, { name: 'A1b' }, { name: 'A1c' }], }, { name: 'A2', child: [{ name: 'A2a' }, { name: 'A2b' }] }, { name: 'A3', child: [{ name: 'A3a' }, { name: 'A3b' }, { name: 'A3c' }, { name: 'A3d' },], }, { name: 'A4', child: [{ name: 'A4a' }, { name: 'A4b' }, { name: 'A4c' }], },], }, { name: 'B', child: [{ name: 'B1', child: [{ name: 'B1a' }, { name: 'B1b' }] }, { name: 'B2', child: [{ name: 'B2a' }, { name: 'B2b' }] }, { name: 'B3', child: [{ name: 'B3A' }, { name: 'B3b' }, { name: 'B3c' }, { name: 'B3d' }, { name: 'B3e' },], },], },];

const condenseArray = (arr) => {
  const res = [];

  let lvl = [];
  for (const { name, child } of arr) {
    lvl.push(name);
    
    if (child?.length) {
      for (const n of condenseArray(child)) {
        lvl.push(...n);
        res.push(lvl);
        lvl = [];
      }
    } else {
      res.push(lvl);
      lvl = [];
    }
  }

  return res;
};

const result = condenseArray(arrayOfObjects);

for (const arr of result) {
  console.log(`[ ${arr.map((n) => `'${n}'`).join(', ')} ]`.padStart(20, ' '));
}

/* Output
[
  ['A', 'A1', 'A1a'],
  ['A1b'],
  ['A1c'],
  ['A2', 'A2a'],
  ['A2b'],
    ...
  ['B', 'B1', 'B1a'],
  ['B1b'],
  ['B2', 'B2a'],
    ...
]
*/
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

But it is clearer both in logic and output to simply create complete rows for each child.

const arrayOfObjects = [{ name: 'A', child: [{ name: 'A1', child: [{ name: 'A1a' }, { name: 'A1b' }, { name: 'A1c' }], }, { name: 'A2', child: [{ name: 'A2a' }, { name: 'A2b' }] }, { name: 'A3', child: [{ name: 'A3a' }, { name: 'A3b' }, { name: 'A3c' }, { name: 'A3d' },], }, { name: 'A4', child: [{ name: 'A4a' }, { name: 'A4b' }, { name: 'A4c' }], },], }, { name: 'B', child: [{ name: 'B1', child: [{ name: 'B1a' }, { name: 'B1b' }] }, { name: 'B2', child: [{ name: 'B2a' }, { name: 'B2b' }] }, { name: 'B3', child: [{ name: 'B3A' }, { name: 'B3b' }, { name: 'B3c' }, { name: 'B3d' }, { name: 'B3e' },], },], },];


const condenseArray = (arr) => {
  const res = [];

  for (const { name, child } of arr) {
    let lvl = [name];

    if (child?.length) {
      for (const n of condenseArray(child)) {
        res.push([...lvl, ...n]);
      }
    } else {
      res.push(lvl);
    }
  }

  return res;
};

const result = condenseArray(arrayOfObjects);

for (const arr of result) {
  console.log(`[ ${arr.map((n) => `'${n}'`).join(', ')} ]`.padStart(20, ' '));
}

/* Output
[
  ['A', 'A1', 'A1a'],
  ['A', 'A1', 'A1b'],
  ['A', 'A1', 'A1c'],
  ['A', 'A2', 'A2a'],
  ['A', 'A2', 'A2b'],
    ...
]
*/
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
pilchard
  • 12,414
  • 5
  • 11
  • 23
-2

I've done that...

const arrayOfObjects = 
  [ { name: 'A', child: 
      [ { name: 'A1', child: 
          [ { name: 'A1a' }, { name: 'A1b' }, { name: 'A1c' } 
        ] } 
      , { name: 'A2', child: 
          [ { name: 'A2a' }, { name: 'A2b' } 
        ] } 
      , { name: 'A3', child: 
          [ { name: 'A3a' }, { name: 'A3b' }, { name: 'A3c' }, { name: 'A3d' } 
        ] } 
      , { name: 'A4', child: 
          [ { name: 'A4a' }, { name: 'A4b' }, { name: 'A4c' } 
    ] } ] } 
  , { name: 'B', child: 
      [ { name: 'B1', child: 
          [ { name: 'B1a' }, { name: 'B1b' } 
        ] } 
      , { name: 'B2', child: 
          [ { name: 'B2a' }, { name: 'B2b' } 
        ] } 
      , { name: 'B3', child: 
          [ { name: 'B3A' }, { name: 'B3b' }, { name: 'B3c' }, { name: 'B3d' }, { name: 'B3e' } 
  ] } ] } ];


const res = [], elm = [];

const AddElm = arr =>
  {
  arr.forEach(({name,child}) =>
    {
    elm.push(name)
    if (!!child)
      AddElm(child);
    else 
      {
      res.push([...elm]);
      elm.length = 0; 
      }
    });
  }

AddElm(arrayOfObjects);

console.log( res );
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

synthetic result

[ [ 'A', 'A1', 'A1a' ] 
, [            'A1b' ] 
, [            'A1c' ] 
, [      'A2', 'A2a' ] 
, [            'A2b' ] 
, [      'A3', 'A3a' ] 
, [            'A3b' ] 
, [            'A3c' ] 
, [            'A3d' ] 
, [      'A4', 'A4a' ] 
, [            'A4b' ] 
, [            'A4c' ] 
, [ 'B', 'B1', 'B1a' ] 
, [            'B1b' ] 
, [      'B2', 'B2a' ] 
, [            'B2b' ] 
, [      'B3', 'B3A' ] 
, [            'B3b' ] 
, [            'B3c' ] 
, [            'B3d' ] 
, [            'B3e' ] 
]  
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40