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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With