There is a use case to filter key/value pairs that have a value of zero out of the following dataset. If all the values are zero for the given key then the key/value pair is to be filtered out entirely (as is the case for keys 41521, 41530).
const simpleData = {
"41511": {
"count": 0,
"probability": 0.000017
},
"41521": {
"count": 0,
"probability": 0
},
"41530": {
"count": 0,
"probability": 0
},
"41540": {
"count": 0,
"probability": 0.000085
},
"41551": {
"count": 1,
"probability": 1
}
};
acc = {};
Object.entries(simpleData).forEach(([key, value]) => {
acc[key] = {};
Object.entries(value).forEach(([k, v]) => {
if (v !== 0) acc[key][k] = v;
});
if (Object.keys(acc[key]).length === 0) delete acc[key];
});
// console.log('simpleData', simpleData);
console.log('acc ', acc);
The current approach uses two .forEach() loops. Is there a different way to do this filtering that avoids multiple .forEach() loops?
CodePudding user response:
Yes, there is another way to achieve the same result that avoids using multiple forEach() loops. Instead of using two forEach() loops, you can use a combination of filter() and map() to filter out the key/value pairs that have a value of zero.
Here's an example of how this can be done:
const simpleData = {
"41511": {
"count": 0,
"probability": 0.000017
},
"41521": {
"count": 0,
"probability": 0
},
"41530": {
"count": 0,
"probability": 0
},
"41540": {
"count": 0,
"probability": 0.000085
},
"41551": {
"count": 1,
"probability": 1
}
};
// Filter out the key/value pairs that have a value of zero
const filteredData = Object.entries(simpleData)
.filter(([key, value]) => {
// Check if all the values in the object are zero
return Object.values(value).every(v => v !== 0);
})
.map(([key, value]) => {
// Return the key/value pair as a new object
return { [key]: value };
});
console.log(filteredData);
In this example, we first use Object.entries() to convert the simpleData object into an array of key/value pairs. We then use filter() to remove any key/value pairs that have a value of zero. Finally, we use map() to convert the remaining key/value pairs back into objects.
CodePudding user response:
Actually multiple loops are not need as you can achieve your goal using the filter method to filter out the items where the count and probability keys equal to 0 or in other words to keep the items that have at least one key from count and probability keys that is not 0.
Here's a live demo:
const simpleData = {
"41511": {
"count": 0,
"probability": 0.000017
},
"41521": {
"count": 0,
"probability": 0
},
"41530": {
"count": 0,
"probability": 0
},
"41540": {
"count": 0,
"probability": 0.000085
},
"41551": {
"count": 1,
"probability": 1
}
},
/**
* filtered array will contain the filtered data.
* we'll only keep the items where at least one of the keys ("count" or "probability") is not equal to "0"
*/
filtered = Object.entries(simpleData).filter(([k, v]) => v['count'] > 0 || v['probability'] > 0);
// print the result
console.log(filtered);
The above method prevents you from having multiple loops but now the filtered array no longer contain object but rather each item will be an array where the key
0is the key from the original object (like41511and the key1is the actual data (like{"count": 0, "probability": 0.000017}.
CodePudding user response:
const simpleData = {
"41511": {
"count": 0,
"probability": 0.000017
},
"41521": {
"count": 0,
"probability": 0
},
"41530": {
"count": 0,
"probability": 0
},
"41540": {
"count": 0,
"probability": 0.000085
},
"41551": {
"count": 1,
"probability": 1
}
};
acc = {};
Object.entries(simpleData).forEach(([key, value]) => {
tmp = Object.entries(value).filter(([, v]) => v !== 0);
if (tmp.length !== 0) acc[key] = Object.fromEntries(tmp);
});
console.log('acc ', acc);
CodePudding user response:
const finalResult = Object.entries(simpleData)
.filter(([eachKey, eachValue]) => {
if (!eachValue["count"] && !eachValue["probability"]) return false;
return true;
})
.map(([eachKey, eachValue]) => {
if (eachValue["count"] && eachValue["probability"]) {
return {
[eachKey]: eachValue,
};
}
if (!eachValue["count"]) {
return {
[eachKey]: {
probability: eachValue["probability"],
},
};
}
if (!eachValue["probability"]) {
return {
[eachKey]: {
count: eachValue["count"],
},
};
}
})
.reduce((prev, current) => {
return {
...prev,
...current,
};
});
console.log("finalResult is", finalResult);
