Search code examples
javascriptarraysgroupingreduceflatmap

Generate a tree with flatMap


I'm trying to turn a flat array into an array of objects with children and I don't know how to do it. Something like that:

//source format

const arrayObjects = [
  { name: "Alice", lastname: "Silva", age: 25, type: "A", city: "São Paulo" },
  { name: "Bruno", lastname: "Pereira", age: 30, type: "A", city: "Belo Horizonte" },
  { name: "Camila", lastname: "Silva", age: 35, type: "B", city: "São Paulo" },
  { name: "Daniel", lastname: "Pereira", age: 40, type: "B", city: "Belo Horizonte" },
  { name: "Eduardo", lastname: "Silva", age: 45, type: "B", city: "Belo Horizonte" },
  { name: "Fernanda", lastname: "Silva", age: 50, type: "A", city: "São Paulo" },
];


//expected format

const arrayOutPut = [
  {
    age: 105,
    type: "A",
    children: [
      {
        age: 75,
        type: "A",
        lastname: "Silva",
        children: [
          { name: "Alice", lastname: "Silva", age: 25, type: "A", city: "São Paulo" },
          { name: "Fernanda", lastname: "Silva", age: 50, type: "A", city: "São Paulo" }
        ]
      },
      {
        age: 30,
        type: "A",
        lastname: "Pereira",
        children: [
          { name: "Bruno", lastname: "Pereira", age: 30, type: "A", city: "Belo Horizonte" }
        ]
      }
    ]
  }
]

What's the most efficient way to do this in JavaScript?

I've tried using something with flatMap and reduce, but it's so messed up in my head that I can't come up with an effective solution.


Solution

  • I can't say if it is the most efficient way, but I would do it this way

    const arrayObjects = [
      { name: "Alice", lastname: "Silva", age: 25, type: "A", city: "São Paulo" },
      { name: "Bruno", lastname: "Pereira", age: 30, type: "A", city: "Belo Horizonte" },
      { name: "Camila", lastname: "Silva", age: 35, type: "B", city: "São Paulo" },
      { name: "Daniel", lastname: "Pereira", age: 40, type: "B", city: "Belo Horizonte" },
      { name: "Eduardo", lastname: "Silva", age: 45, type: "B", city: "Belo Horizonte" },
      { name: "Fernanda", lastname: "Silva", age: 50, type: "A", city: "São Paulo" },
    ];
    
    // get unique types
    const types = [...new Set(arrayObjects.map(({type}) => type))];
    
    
    const result = types.map(type => {
    // get children by type
     const children = arrayObjects.filter(obj => obj.type === type)
     .sort((a, b) => a.age - b.age)
     
     // get total age
     const age = children.reduce((acc, {age}) => acc += age,0)
     
     return {type, age, children}
    });
    
    console.log(result);