Home > Enterprise >  javascript create a mapping of string to array of objects from an array of objects
javascript create a mapping of string to array of objects from an array of objects

Time:05-23

Is there a way to create a map (mapping string to array) from an array in the example below using map function? Not sure how to append an object to a key that already exists instead of overwriting what's inside already

WANT {"Germany": [{score: 1}], "Austria": [{score: 1}], "Switzerland": [{score: 2},{score: 3}]}

GETTING {"Germany": [{score: 1}], "Austria": [{score: 1}], "Switzerland": [{score: 3}]}

let data = [
  {country: 'Germany', score: 1},
  {country: 'Austria', score: 1},
  {country: 'Switzerland', score: 2},
  {country: 'Switzerland', score: 3}
];

let dictionary = Object.assign({}, ...data.map((x) => ({[x.country]: [{score: x.score}]})));

CodePudding user response:

Fairly straightforward to do with reduce(), some destructuring and spread syntax:

const data = [
  {country: 'Germany', score: 1},
  {country: 'Austria', score: 1},
  {country: 'Switzerland', score: 2},
  {country: 'Switzerland', score: 3}
];

const result = data.reduce((a, {country, score}) => ({
  ...a,
  [country]: [...a[country] || [], {score}]
}), {});

console.log(result);

CodePudding user response:

You could use the reduce function, which take an array and return a value based on some operation done on every element of the array.

In your case, this operation could be to add the score to an already existing key, in another object.

The reduce function take a callback with two parameter, a collector and a current item.

let data = [
  {country: 'Germany', score: 1},
  {country: 'Austria', score: 1},
  {country: 'Switzerland', score: 2},
  {country: 'Switzerland', score: 3}
];

// since the reduce function returns a new object, we don't need to deep copy it.
let dictionary = data.reduce((collector, x) => {
  // we first have to check if the key exists in the collector object.
  // to do so, we use the `in` operator, and negate it's output.
  if(!(x.country in collector)) {
    collector[x.country] = [];
  }
  
  // we, then, can push the current element's score into the appropriate array
  collector[x.country].push({score: x.score});
  
  // and we need to return the updated value. In our case, it's the collector.
  return collector;
}, {} /** the secon parameter of the function is the initials value of the collector */);

console.log(dictionary)

CodePudding user response:

You can use Array.prototype.reduce() to achive it.

Try like below:

let data = [
  { country: "Germany", score: 1 },
  { country: "Austria", score: 1 },
  { country: "Switzerland", score: 2 },
  { country: "Switzerland", score: 3 },
];

const output = data.reduce((prev, { country, score }) => {
  if (prev[country]) {
    prev[country].push({ score });
  } else {
    prev[country] = [{ score }];
  }
  return prev;
}, {});

console.log(output);

  • Related