Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get count from Array of arrays

I have an array of arrays below. With ES6, how can I get a count of each value Good, Excellent & Wow into a new array e.g [{name: Good, count: 4} {name: Excellent, count: 5}, {name:Wow, count:2}] in dynamic style. I am attempting to use Object.assign but I am failing to "unique" out the count of the key plus instead, I need to use an array as I am trying to render this out on the front end. Do I need to use reduce? how?

let k = 0
const stats = {}
const remarks = [
  [{name: "Good"}],
  [{name: "Good"}, {name: "Excellent"}],
  [{name: "Good"}, {name: "Excellent"}, {name: "Wow"}],
  [{name: "Good"}, {name: "Excellent"}, {name: "Wow"}],
  [{name: "Excellent"}],
  [{name: "Excellent"}]
]

remarks.forEach((arr) => {
  arr.map((e) => {
    Object.assign(stats, { [e.name]: k = k + 1 })
  })
})

console.log(stats);

Output:

stats: {Good: 8, Excellent: 11, Wow: 9}

Which is Incorrect plus I need to use an array.

Expected output:

[{name: Good, count: 4} {name: Excellent, count: 5}, {name:Wow, count:2}]

like image 846
colin_dev256 Avatar asked Aug 22 '19 18:08

colin_dev256


People also ask

How do you count an array of arrays?

Answer: Use the PHP count() or sizeof() function You can simply use the PHP count() or sizeof() function to get the number of elements or values in an array. The count() and sizeof() function returns 0 for a variable that has been initialized with an empty array, but it may also return 0 for a variable that isn't set.

How do you count the number of times a value appears in an array?

To check how many times an element appears in an array: Use the forEach() method to iterate over the array. Check if the current element is equal to the specific value. If the condition is met, increment the count by 1 .


3 Answers

Flatten the array of arrays and reduce it starting with an object like : { Good: 0, Excellent: 0, Wow: 0}

then .map the Object.entries of the result to transform it to an array :

const remarks = [
  [{ name: "Good" }],
  [{ name: "Good" }, { name: "Excellent" }],
  [{ name: "Good" }, { name: "Excellent" }, { name: "Wow" }],
  [{ name: "Good" }, { name: "Excellent" }, { name: "Wow" }],
  [{ name: "Excellent" }],
  [{ name: "Excellent" }]
];

const result = Object.entries(
  remarks.flat().reduce(
    (all, { name }) => {
      all[name] += 1;
      return all;
    },
    { Good: 0, Excellent: 0, Wow: 0 }
  )
).map(([name, count]) => ({ name, count }));

console.log(result);
like image 138
Taki Avatar answered Sep 20 '22 02:09

Taki


You can try below logic:

var data = [[{name: "Good"}],[{name: "Good"}, {name:"Excellent"}],[{name: "Good"}, {name:"Excellent"}, {name:"Wow"}],[{name: "Good"}, {name:"Excellent"}, {name:"Wow"}],[{name:"Excellent"}],[{name:"Excellent"}]]

var nData = [];

(data || []).forEach( e => {
  (e || []).forEach(ei => {
    var i = (index = nData.findIndex(d => d.name === ei.name)) >=0 ? index : nData.length;
    nData[i] = {
      name: ei.name,
      count : (nData[i] && nData[i].count ? nData[i].count : 0)+1
    }
  });
});

console.log(nData);

Hope this helps!

like image 38
Hardik Shah Avatar answered Sep 22 '22 02:09

Hardik Shah


You can use reduce, then convert the result into an array of objects:

const counts = remarks.reduce((result, list) => {
  list.forEach(remark => {
    result[remark.name] = (result[remark.name] || 0) + 1;
  });
}, {});
const finalResult = [];
for (let name in counts) {
  finalResult.push({name, count: counts[name]});
}
like image 39
IceMetalPunk Avatar answered Sep 20 '22 02:09

IceMetalPunk