To give some background: By using Postman (the REST api tool) we are comparing XMLs to a template by converting the XMLs to JSON and compare those as Javascript objects. The comparison can handle wildcards in the values and will return a new JS object (or JSON) with only the differences. When there are no differences, I receive an empty object which is the correct state. In some cases empty values or objects are returned and we remove them from the object with a clean step.
This is how the clean function looks like:
Utils = {
clean: function(object) {
Object
.entries(object)
.forEach(([k, v]) => {
if (v && typeof v === 'object')
Utils.clean(v);
if (v && typeof v === 'object' && !Object.keys(v).length || v === null || v === undefined)
Array.isArray(object) ? object.splice(k, 1) : delete object[k];
});
return object;
}
}
This works fine for most cases except when we have an array with multiple the same empty object because of the object.splice
in combination with the foreach
as pointed out here.
Normally, I would use a filter function, use _.pickBy
from lodash or iterate backwards through the array, but because of the layout of the clean
function, I can not figure out how to do that.
Can you help me to point out what I need to do to remove multiple empty items and objects from an array correctly.
Real life testcase:
var x = {"Document":{"CstmrDrctDbtInitn":{"GrpHdr":{},"PmtInf":{"DrctDbtTxInf":[{"PmtId":{}},{"PmtId":{}},{"PmtId":{}},{"PmtId":{}},{"PmtId":{}}]}}}};
console.log(JSON.stringify(Utils.clean(x)));
// returns {"Document":{"CstmrDrctDbtInitn":{"PmtInf":{"DrctDbtTxInf":[{},{}]}}}}
// desired result: {}
Other testcases:
console.log(JSON.stringify(Utils.clean({"a": [null,null,"b","c",{},{},{},{}]})));
// returns {"a":[null,"c",{},{},{}]}
// desired: {"a":["b", "c"]}
console.log(JSON.stringify(Utils.clean({"a": [null,null,"b","c",{"d": {}},{}]})));
// returns {"a":[null,"c",{},{}]}
// desired: {"a":["b", "c"]}
console.log(JSON.stringify(Utils.clean({ "a" : [null,null,{"d": {}, "e": [null, {}]},{}]})));
// returns {"a":[null,{}]}
// desired: {}