4

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"
}]]
1

3 Answers 3

4

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);

Sign up to request clarification or add additional context in comments.

1 Comment

There's no need to constantly clone acc just to get that into a one-liner. Just append the new property and return acc.
3

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);

Comments

0

A simply solution easy to understand! Iterate all peopleData and put them in a new object using the array headers:

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

let result = [];

peopleData.forEach((e, i) => {   //iterate data
  result[i] = {};
  result[i][headers[0]] = e[0];
  result[i][headers[1]] = e[1];
  result[i][headers[2]] = e[2];
});

console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.