Count how many objects of each value has in array

  • A+
Category:Languages

I have this array:

var markers = [   {     "type":"Chocolate",     "name":"KitKat",     "group":"candy",     "icon":"candy",     "coords":[5246,8980],   },   {     "type":"Fruit",     "name":"Orange",     "group":"fruits",     "icon":"fruis",     "coords":[9012,5493],   },   {     "type":"Fruit",     "name":"Banana",     "group":"fruits",     "icon":"fruis",     "coords":[9012,5493],   },   {     "type":"Food",     "name":"Rice",     "group":"foods",     "icon":"foods",     "coords":[6724,9556],   },   {     "type":"Food",     "name":"Meat",     "group":"foods",     "icon":"foods",     "coords":[6724,9556],   },   {     "type":"Food",     "name":"Beam",     "group":"foods",     "icon":"foods",     "coords":[6724,9556],   },   {     "type":"Liquid",     "name":"Water",     "group":"liquids",     "icon":"liquids",     "coords":[6724,9556],   },   {     "type":"Liquid",     "name":"Coffe",     "group":"liquids",     "icon":"liquids",     "coords":[6724,9556],   }, ] 

Which I want to count how many items each group has in this array.

I managed to count it with this:

var count = []  for (var i = 0; i < markers.length; i++) {   count[markers[i].group] = count[markers[i].group] + 1 || 1 ; } 

Which outputs this result:

count = [ candy: 1 foods: 3 fruits: 2 liquids: 2 ] 

I want to use this values in another part, and for that I need to change the array structure, to something like this:

count = [ {"item": "candy","qnt":1}, {"item": "foods","qnt":3}, {"item": "fruits","qnt":2}, {"item": "liquids","qnt":2} ] 

I know that I could do something like this:

var total_fruits = 0; for (var i = 0; i < markers.length; i++) {   if (markers[i].group == "fruits"){     total_fruits++   } } 

But imagine how many if's I will need for a group of more than 50 types...

I will use the values in the html part with the same class that the item value is like this:

<ul>   <li class="candy">     <span class="qnt">1</span>   </li>   <li class="fruits">     <span class="qnt">2</span>   </li>   <li class="foods">     <span class="qnt">3</span>   </li>   <li class="liquids">     <span class="qnt">2</span>   </li> </ul> 

Any suggestions or how to improve this?

 


You can use the reduce method to return a new array with the items and quantities.

We use a ternary statement to determine if the accumulator array already contains the group type with findIndex. If it doesn't we push the new type with a qnt of 1, if it does we simply increment the qnt value.

markers.reduce((ms, m) => (ms.findIndex(o => o.item === m["group"]) > 0) ?  (ms[ms.findIndex(o => o.item === m["group"])]["qnt"]++, ms) :  (ms.push({  qnt: 1,  item: m["group"]}), ms), []); 
var markers=[{type:"Chocolate",name:"KitKat",group:"candy",icon:"candy",coords:[5246,8980]},{type:"Fruit",name:"Orange",group:"fruits",icon:"fruis",coords:[9012,5493]},{type:"Fruit",name:"Banana",group:"fruits",icon:"fruis",coords:[9012,5493]},{type:"Food",name:"Rice",group:"foods",icon:"foods",coords:[6724,9556]},{type:"Food",name:"Meat",group:"foods",icon:"foods",coords:[6724,9556]},{type:"Food",name:"Beam",group:"foods",icon:"foods",coords:[6724,9556]},{type:"Liquid",name:"Water",group:"liquids",icon:"liquids",coords:[6724,9556]},{type:"Liquid",name:"Coffe",group:"liquids",icon:"liquids",coords:[6724,9556]}];  let r = markers.reduce((ms, m) => (ms.findIndex(o => o.item === m["group"]) > 0) ?  (ms[ms.findIndex(o => o.item === m["group"])]["qnt"]++, ms) :  (ms.push({  qnt: 1,  item: m["group"]}), ms), []);  console.log(r);

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: