Let's say I have some data organized like so...
dataArr = [
{service: s1, status: ready},
{service: s2, status: ready},
{service: s1, status: retired},
{service: s3, status: retired},
{service: s2, status: ready}
]
There are 3 distinct services. Each data element has one of the three service types, and has a status of either retired or ready.
How can I loop through each element in the dataArr to create the following statusByServiceObj? For instance, within all the data, I want to find all s1 service types, and then determine how many s1's are in a retired or ready state.
statusByServiceObj = {
{s1: {ready: 1, retired: 1} },
{s2: {ready: 2, retired: 0} },
{s3: {ready: 0, retired: 1} },
}
Where I am currently, I have looped through the dataArr array to create an object like so:
let obj = {};
let nestedObj = {};
dataArr.forEach(ele => {
obj[ele.service] = nestedObj;
nestedObj[ele.status] = 0;
});
// obj now equals...
obj = {
{s1: {ready: 0, retired: 0} },
{s2: {ready: 0, retired: 0} },
{s3: {ready: 0, retired: 0} },
}
I'm struggling to populate the ready and retired counts based on service type, when looping through my dataArr.
Very open to best practice recommendations, new to JS. I feel like I'm going braindead when applying the 0 value... should be a count of sorts. Or possibly converting the Object of Objects to an Array of Objects...
I attemted to count the status values by services like so:
dataArr.forEach(ele => {
for (let service in obj) {
let countsObj = obj[service];
for (let status in countsObj) {
if (ele.service === service && ele.status === status) {
countsObj[status = countsObj[status] + 1;
}
}
}
}
However, this returns on obj that's getting the total counts of each status in the entire dataArr, ready or retired, and applies it to each service object:
obj = {
{s1: {ready: 3, retired: 2} },
{s2: {ready: 3, retired: 2} },
{s3: {ready: 3, retired: 2} },
}
You can use reduce to achieve the desired result
const dataArr = [
{ service: "s1", status: "ready" },
{ service: "s2", status: "ready" },
{ service: "s1", status: "retired" },
{ service: "s3", status: "retired" },
{ service: "s2", status: "ready" },
];
const result = dataArr.reduce((acc, curr) => {
const { service, status } = curr;
if (!acc[service]) acc[service] = { ready: 0, retired: 0 };
acc[service][status] += 1;
return acc;
}, {});
console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }