0

I have array object -

[
 { 
  department:"Reviewer",
  name:"John"
 },
 { 
  department:"Reviewer",
  name:"Carol"
 },
 { 
  department:"Reviewer",
  name:"June"
 },
 { 
  department:"Assistant Reviewer",
  name:"Mac"
 },
 { 
  department:"Assistant Reviewer",
  name:"Issac"
 }
]

I want to convert this object into array object as below -

[
     { 
      department:"Reviewer",
      name:"John;Carol;June;"
     },
     { 
      department:"Assistant Reviewer",
      name:"Mac;Issac;"
     },
]

I tried using filter -

[... new Set(obj.department)].map((item)=>{return {item.name+";"} });

But this operation is dealing with only one element per item. Its not accumulating names.

holydragon
  • 6,158
  • 6
  • 39
  • 62
C Sharper
  • 8,284
  • 26
  • 88
  • 151
  • Possible duplicate of [How to group by and sum an array of objects?](https://stackoverflow.com/questions/29364262) and [Group by similar attribute and join them by comma javascript - Mysql group concat like](https://stackoverflow.com/questions/50148383) – adiga Feb 03 '23 at 06:23
  • @Unmitigated it's the exact same operators. Use `+` operator on strings instead of numbers. This is probably a better target: [Group by similar attribute and join them by comma javascript - Mysql group concat like](https://stackoverflow.com/questions/50148383) – adiga Feb 03 '23 at 06:26

4 Answers4

2

Get a set of distinct departments, then map from them to the list of names

const data = [{"department":"Reviewer","name":"John"},{"department":"Reviewer","name":"Carol"},{"department":"Reviewer","name":"June"},{"department":"Assistant Reviewer","name":"Mac"},{"department":"Assistant Reviewer","name":"Issac"}]

console.log([...new Set(data.map(i=>i.department))].map(i=>({
  department: i, 
  name: data.filter(j=>j.department===i).map(j=>j.name).join(';')+';'})))

or, using reduce:

const data = [{"department":"Reviewer","name":"John"},{"department":"Reviewer","name":"Carol"},{"department":"Reviewer","name":"June"},{"department":"Assistant Reviewer","name":"Mac"},{"department":"Assistant Reviewer","name":"Issac"}]

console.log(Object.values(data.reduce((a,{department, name})=>
  (((a[department]??={department,name:''}).name+=`${name};`),a),{})))
Andrew Parks
  • 6,358
  • 2
  • 12
  • 27
1

This would also work:

const input = [ { department: "Reviewer", name: "John", }, { department: "Reviewer", name: "Carol", }, { department: "Reviewer", name: "June", }, { department: "Assistant Reviewer", name: "Mac", }, { department: "Assistant Reviewer", name: "Issac", }, ];

const output = input.reduce((prev, { department, name }) => {
  const match = prev.find((item) => item.department === department);
  if (match) {
    match.name = `${match.name};${name}`;
  } else {
    prev.push({ department, name });
  }
  return prev;
}, []);

console.log(output);

Using Array.prototype.reduce() and Array.prototype.find()

Amila Senadheera
  • 12,229
  • 15
  • 27
  • 43
1

Here is a solution using:

  • .reduce() to build an object that maps from department (aka key) to names (aka value)
  • .map() to transform that object into an array of objects with desired format

Note that this solution is faster than an array index search (aka other answers here) for large a large input array, at the cost of using a bit more memory.

const array = [
  { department: "Reviewer", name: "John" },
  { department: "Reviewer", name: "Carol" },
  { department: "Reviewer", name: "June" },
  { department: "Assistant Reviewer", name: "Mac" },
  { department: "Assistant Reviewer", name: "Issac" }
];

const result = Object.entries(array.reduce((acc, obj) => {
  if(acc[obj.department]) {
    acc[obj.department] += obj.name + ';';
  } else {
    acc[obj.department] = obj.name + ';';
  }
  return acc;
}, {})).map(arr => ({ department: arr[0], name: arr[1] }));

console.log(result);
Peter Thoeny
  • 7,379
  • 1
  • 10
  • 20
1

This codes should work:

let data = [
  { department: "Reviewer", name: "John" },
  { department: "Reviewer", name: "Carol" },
  { department: "Reviewer", name: "June" },
  { department: "Assistant Reviewer", name: "Mac" },
  { department: "Assistant Reviewer", name: "Issac" }
];

let newData = [];
data.forEach((obj)=>{
  if(newData.filter(m => m.department == obj.department).length) {
    newData.find(n => n.department == obj.department).name += obj.name + ';'; 
  } else {
    newData.push({
      department: obj.department,
      name: obj.name + ';'
    })
  } 
});
console.log(newData);
Jordy
  • 1,802
  • 2
  • 6
  • 25