Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to join 2 arrays into an array of objects

I've got some headers and peopleData:

const headers = ["name", "age", "nationality"]

const peopleData = [
  ["John", 31, "Spanish"],
  ["Jane", 41, "Italian"],
  ["Johnson", 11, "Thai"],
  ["Rob", 13, "Japanese"],
]

I want to combine both and return an array of objects looking like:

[{
  name: "John",
  age: 31,
  nationality: "Spanish"
}, {
  name: "Jane",
  age: 41,
  nationality: "Italian"
}, {
  name: "Johnson",
  age: 11,
  nationalityL: "Thai"
}, {
  name: "Rob",
  age: 13,
  nationality: "Japanese"
}]

So far I came up to this:

const people = peopleData.map((person, i) => {
  return headers.map((header, index) => {
    return {
      [header]: person[index]
    }
  })
})

This solution does not work since it creates nested objects:

[[{
  name: "John"
}, {
  age: 31
}, {
  nationality: "Spanish"
}], [{
  name: "Jane"
}, {
  age: 41
}, {
  nationality: "Italian"
}], [{
  name: "Johnson"
}, {
  age: 11
}, {
  nationality: "Thai"
}], [{
  name: "Rob"
}, {
  age: 13
}, {
  nationality: "Japanese"
}]]
like image 835
SixtyEight Avatar asked Mar 02 '23 12:03

SixtyEight


2 Answers

Example below:

Credit to Andreas comment, better performant below

const headers = ["name", "age", "nationality"];

const peopleData = [
  ["John", 31, "Spanish"],
  ["Jane", 41, "Italian"],
  ["Johnson", 11, "Thai"],
  ["Rob", 13, "Japanese"],
];

const o = peopleData.map(a =>
  a.reduce((acc, b, i) => {
    acc[headers[i]] = b;
    return acc;
  }, {})
);

console.log(o);

In one line-er, but less performent

const headers = ["name", "age", "nationality"];

const peopleData = [
  ["John", 31, "Spanish"],
  ["Jane", 41, "Italian"],
  ["Johnson", 11, "Thai"],
  ["Rob", 13, "Japanese"],
];

const o = peopleData.map(a =>
  a.reduce((acc, b, i) => ({ ...acc, [headers[i]]: b }), {})
);

console.log(o);
like image 57
ikhvjs Avatar answered Mar 08 '23 22:03

ikhvjs


You can wrap your inner .map() in a call to Object.fromEntries() which will build an object for you - it takes an array of [[key, value],...] pairs, and so you can change your inner map to return a [key, value] pair array instead of objects like so:

const headers = ["name", "age", "nationality"];
const peopleData = [ ["John", 31, "Spanish"], ["Jane", 41, "Italian"], ["Johnson", 11, "Thai"], ["Rob", 13, "Japanese"], ];

const res = peopleData.map(person => Object.fromEntries(person.map(
  (val, i) => [headers[i], val]
)));

console.log(res);

Or, you can stick with your approach of returning an array of objects, but then merge the objects within the array together using Object.assign() and the spread syntax ...:

const headers = ["name", "age", "nationality"];
const peopleData = [ ["John", 31, "Spanish"], ["Jane", 41, "Italian"], ["Johnson", 11, "Thai"], ["Rob", 13, "Japanese"], ];

const res = peopleData.map(person => Object.assign(...person.map(
  (val, i) => ({[headers[i]]: val})
)));

console.log(res);
like image 41
Nick Parsons Avatar answered Mar 09 '23 00:03

Nick Parsons