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
0
is the key from the original object (like41511
and the key1
is 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);