Aggregate array of objects on the given keys

Given an array of objects and two keys “on” and “who”, aggregate the “who” values on the “on” values.

Example

Input:
const endorsements = [ 
  { skill: 'css', user: 'Bill' }, 
  { skill: 'javascript', user: 'Chad' }, 
  { skill: 'javascript', user: 'Bill' }, 
  { skill: 'css', user: 'Sue' }, 
  { skill: 'javascript', user: 'Sue' }, 
  { skill: 'html', user: 'Sue' } 
];

console.log(aggregate(endorsements, "user", "skill"));

Output:
[
  {
    "user": "Bill",
    "skill": [
      "css",
      "javascript"
    ]
  },
  {
    "user": "Chad",
    "skill": [
      "javascript"
    ]
  },
  {
    "user": "Sue",
    "skill": [
      "css",
      "javascript",
      "html"
    ]
  }
]

We will use Array.reduce() to aggregate the values of the array of objects. All we have to do is

  • Get the value of the on key and aggregate the values of the who key in the format in which we have to return output.
  • Then only return the values from the aggregation as we are expecting an array of objects as output.
const aggregate = (arr, on, who) => {
  // using reduce() method to aggregate 
  const agg = arr.reduce((a, b) => {
    // get the value of both the keys 
    const onValue = b[on];
    const whoValue = b[who];
    
    // if there is already a key present
    // merge its value
    if(a[onValue]){
      a[onValue] = {
        [on]: onValue,
        [who]: [...a[onValue][who], whoValue]
      }
    }
    // create a new entry on the key
    else{
      a[onValue] = {
        [on]: onValue,
        [who]: [whoValue]
      }
    }
    
    // return the aggregation
    return a;
  }, {});
  
  
  // return only values after aggregation 
  return Object.values(agg);
}
Input:
const endorsements = [ 
  { skill: 'css', user: 'Bill' }, 
  { skill: 'javascript', user: 'Chad' }, 
  { skill: 'javascript', user: 'Bill' }, 
  { skill: 'css', user: 'Sue' }, 
  { skill: 'javascript', user: 'Sue' }, 
  { skill: 'html', user: 'Sue' } 
];

console.log(aggregate(endorsements, "skill", "user"));

Output:
[
  {
    "skill": "css",
    "user": [
      "Bill",
      "Sue"
    ]
  },
  {
    "skill": "javascript",
    "user": [
      "Chad",
      "Bill",
      "Sue"
    ]
  },
  {
    "skill": "html",
    "user": [
      "Sue"
    ]
  }
]