-1

I want to iterate over an object array and return another object array with count of records based on a particular property value kind of like a hashtable.

For example:

Array1 = [
  { "name": "Pam", "role": "ceo" },
  { "name": "Joel", "role": "engineer" },
  { "name": "Mary", "role": "ceo" },
  { "name": "Alice", "role": "analyst" },
  { "name": "John", "role": "analyst" },
  { "name": "Nick", "role": "engineer" },
  { "name": "Sam", "role": "analyst" }
]

Expected output:

Array2 = [
  { key: "ceo", count: 2 },
  { key: "engineer", count: 2 },
  { key: "analyst", count: 3 }
]

I need a code that generates Array2 from Array1. Really appreciate the help :)

Solved my problem, thanks

adiga
  • 34,372
  • 9
  • 61
  • 83
shr
  • 31
  • 1
  • 5
  • what have you tried so far? – Doug Jun 27 '18 at 16:56
  • 1
    Possible duplicate of [JavaScript - Count duplicates within an Array of Objects](https://stackoverflow.com/questions/10541068/javascript-count-duplicates-within-an-array-of-objects) – isherwood Jun 27 '18 at 16:57

4 Answers4

2

You can use reduce to group the array of objects into a single object. Use Object.values to convert the object back into an array.

let Array1 = [{"name":"Pam", "role":"ceo"}, {"name":"Joel", "role":"engineer"}, {"name":"Mary", "role":"ceo"}, {"name":"Alice", "role":"analyst"}, {"name":"John", "role":"analyst"}, {"name":"Nick", "role":"engineer"}, {"name":"Sam", "role":"analyst"}]

let Array2 = Object.values(Array1.reduce((c, {role}) => {
  c[role] = c[role] || {key: role,count: 0};
  c[role].count++;
  return c;
}, {}));

console.log(Array2);
Eddie
  • 26,593
  • 6
  • 36
  • 58
1

Should be fairly straightforward to understand. Check the code.

let array1 = [
  { name: "Pam", role: "ceo" },
  { name: "Joel", role: "engineer" },
  { name: "Mary", role: "ceo" },
  { name: "Alice", role: "analyst" },
  { name: "John", role: "analyst" },
  { name: "Nick", role: "engineer" },
  { name: "Sam", role: "analyst" }
];

let obj = {};

array1.forEach(entry => (obj[entry.role] = (obj[entry.role] || 0) + 1));
let array2 = [];
for (role in obj) {
  array2.push({ key: role, count: obj[role] });
}

console.log(array2);
mehulmpt
  • 15,861
  • 12
  • 48
  • 88
  • The properties of Array2 are in the form of string. Is there any way to getting rid of the quotes? i.e. instead of {"key": "engineer", "count": 2} I need {key: "engineer", count: 2} – shr Jun 27 '18 at 17:30
  • @shr quotes do not matter. Infact, they're good in case you have key names which contain special chars – mehulmpt Jun 27 '18 at 17:31
  • Yeah, normally I would agree, but I am using this object later as data for highcharts. And for some reason the chart doesn't get plotted if there are quotes present. – shr Jun 27 '18 at 17:35
1

You have to create a hashmap/object to keep track of the unique counts.

For example:

let Array1=[{"name":"Pam", "role":"ceo"}, {"name":"Joel", "role":"engineer"}, {"name":"Mary", "role":"ceo"}, {"name":"Alice", "role":"analyst"}, {"name":"John", "role":"analyst"}, {"name":"Nick", "role":"engineer"}, {"name":"Sam", "role":"analyst"}]

let hashMap = {}

for(var employee of Array1){
  
  //if that role exists
  if(employee.role in hashMap ){
  
  //up the prev count
  hashMap[employee.role] = hashMap[employee.role] + 1; 
  
  }else{
   hashMap[employee.role] = 1;
  }
}

//now we will iterate through those keys of the Map and format it for Array 2

let outputArray = []
Object.keys(hashMap).forEach(key => {
  
  outputArray.push({
    key,
    count: hashMap[key]
  })
})

console.log(outputArray)
Ravi L
  • 1,142
  • 9
  • 17
0

Here you have two variations, as object and as array. (ES6 required)

let arr = [
  {"name":"Pam", "role":"ceo"},
  {"name":"Joel", "role":"engineer"},
  {"name":"Mary", "role":"ceo"},
  {"name":"Alice", "role":"analyst"}, 
  {"name":"John", "role":"analyst"}, 
  {"name":"Nick", "role":"engineer"},
  {"name":"Sam", "role":"analyst"}
]

let objResult = arr.reduce((acc, obj) => {
    acc[obj.role] = (acc[obj.role] || 0) + 1;
    return acc;
}, {});

console.log(objResult);

let arrResult = Object.keys(objResult).map(k => ({[k]: objResult[k]}));

console.log(arrResult)
V. Sambor
  • 12,361
  • 6
  • 46
  • 65