Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count how many objects in an array has a certain value (JavaScript)

Tags:

javascript

I have an array of objects, like so:

[
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "[email protected]",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "[email protected]",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "[email protected]",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]

In the future this array will contain much more objects. I'm trying to solve this using map and for it seems to be quite complicated. That's the challenge: how I can count how many objects have certain value? How can I get to know how many times someone booked something to day===1? The best result would be an array like this:

[{dayOne: 2}, {dayTwo: 5}, {dayThree:1}.......and so on], 

where value is the value of how many times a day was booked(key), hence how many times certain object(with certain value) has appeared in the array?

Thank you in advance!

like image 516
Murakami Avatar asked Mar 07 '26 14:03

Murakami


1 Answers

To count objects by a condition, you can use .filter --

let firstDayCount = arr.filter(x => x.day === "1").length;

To group the result by days, you can use .reduce --

let countByDays = 
  arr.reduce((res, { day }) => {
     res[day] = res[day] || 0;
     res[day] += 1;
     return res; 
   }, {}); 

If you want to format your output, you can then use a dictionary of names --

let dayNames = { 1: "dayOne", 2: "dayTwo" /* and so on */}

let formattedResult = 
  Object.keys(countByDays)
    .map(n => { [dayNames[n]]: countByDays[n] });

Note that using a .filter for counting creates an intermediate throw-away array. We're not storing a reference anywhere, so it has to be GCed soon, but if it really affects your performance measurably in a real-life scenario, you can use a .reduce instead -- something that is called "deforestation":)

let count = arr.reduce((cnt, el) => el.day === "1" ? cnt += 1 : cnt, 0);

It'll still create an intermediate anonymous object though -- a reducer function -- so if your profiler shows this place as a bottleneck, you might be best off using a for loop. As always in such cases, it's up to you to find the right spot between performance and readability in your own real-world scenarios.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!