Jenny Le
Jenny Le

Reputation: 33

flatten array and put child array into an array of object

I struggled with a problem for more than an hour, how can I turn this nested array

[
    [
        {
            "name": "1",
        }
    ],
    [
        {
            "name": "a",
        },
        {
            "name": "b",
        }
    ]
]

into this:

[
    {
      name: '1',
    },
    {
      id: 'a-b',
      grouped: [
        {
          name: 'a',
          
        },
        {
          name: 'b',
        },
      ],
    },
  ]

I don't mind using lodash. Not sure should I flatten it before anything else would make things easier.

Upvotes: 0

Views: 376

Answers (4)

Andrei Cleland
Andrei Cleland

Reputation: 436

const array1 = [
  [{ name: "1" }],
  [
    { name: "a" },
    { name: "b" }
  ]
]
const array2 = [
  [{ name: "2" }],
  [
    { name: "aa" },
    { name: "bb" },
    { name: "cc" }
  ]
]

transformArray( array1 )
transformArray( array2 )

function transformArray( array ){
  const result = []
    // destructure first array element for the first object:
  const [ nameObj ] = array[0]
  result.push( nameObj )
  
    // map each object of the second array element into an
    // an array of names, and then join the names together:
  const dataObj   = {}
  dataObj.id      = array[1].map(obj => obj.name).join('-')
  dataObj.grouped = array[1]
  result.push( dataObj )
  
  console.log( result )
  return result      
}

Upvotes: 1

Andrei Cleland
Andrei Cleland

Reputation: 436

to flatten the array is a good start. That will remove the superfluous dimension from the rawArray:

const newArray = array.flat()

Now you have an array with three simple objects. The first will remain unchanged. The second element of your finalArray needs to be an object, so let's create it:

const obj = {}

the obj has two keys: id and grouped. The property of id is a string that we can create like this:

obj.id = newArray[1].name + "-" + newArray[2].name 

the property of grouped remains the same:

obj.grouped = array[1]

so the finalArray is now straight forward:

const finalArray = [ newArray[0], obj ]

Put it all together in a function:

const rawArray1 = [
    [
        {
            "name": "1a",
        }
    ],
    [
        {
            "name": "a",
        },
        {
            "name": "b",
        }
    ]
]
const rawArray2 = [
    [
        {
            "name": "1b",
        }
    ],
    [
        {
            "name": "aa",
        },
        {
            "name": "bb",
        }
    ]
]

transformArray( rawArray1 )
transformArray( rawArray2 )
function transformArray( array ){
    const newArray = array.flat()
    const obj = {}
    obj.id = newArray[1].name + "-" + newArray[2].name 
    obj.grouped = array[1]
    const finalArray = [ newArray[0], obj ]

    console.log(finalArray)
    return finalArray
}

Upvotes: 2

Jenny Le
Jenny Le

Reputation: 33

I managed to solve it using simple forEach, push, and flat. It's more simple than I thought, I was confused and stuck with map and reduce.

let result = [];

[
  [{
    "name": "1",
  }],
  [{
      "name": "a",
    },
    {
      "name": "b",
    }
  ]
].forEach((val) => {
  const [{
    name
  }] = val

  if (val.length === 1) {
    result.push({
      name,
    })
  } else if (val.length > 1) {
    result.push({
      id: val.map(val2 => val2.name).join('-'),
      grouped: val
    })
  }
})

console.log(result.flat())

Upvotes: 1

axtcknj
axtcknj

Reputation: 367

You could use map() to form the id and grab the parts needed to reconstruct the new array.

const data = [
  [{
    "name": "1",
  }],
  [{
      "name": "a",
    },
    {
      "name": "b",
    }
  ]
];

const result = [
 ...data[0],
 {
   id: data[1].map(r => r.name).join("-"), 
   grouped: data[1]
 }
];

console.log(result);

Upvotes: 2

Related Questions