'clean up object lead to lost of 0 value
I came across a list of data operations and lost value of [0].
I could not find out why. it's good if I change value to [1], but if i put value [0], then it's gone.
Here is the code:
let data = {
title:"hello world",
value: [0]
}
let sanitized = removeNull(data);
console.log(sanitized)
// ------------------------------------------------------------------------
function removeNull(obj) {
Object.keys(obj).forEach(k =>
(obj[k] && typeof obj[k] === 'object') && removeNull(obj[k]) ||
(typeof obj[k] !== 'boolean' && !obj[k] && obj[k] !== undefined) && delete obj[k]
);
return obj;
};
Solution 1:[1]
Update
Ahhh,typeof obj[k] !== 'boolean' && !obj[k] && obj[k] !== undefined evaluates to true because 0 is considered falsy in Javascript. So !obj[k] is true.
Original answer
The current removeEmpty function is testing if the result of JSON.stringify(o[k] === "[0]") is truthy. You probably meant to test if the stringified contents of o[k] are equal to "[0]". So something like JSON.stringify(o[k]) === "[0]" should solve your problem.
Solution 2:[2]
Some key concepts:
0is falseytypeof null === 'object'is truetypeof [] === 'object'is true
Currently, the code executes as follows:
- When you get to the part of the loop where
obj[k]=[0], removeNull() gets called on[0]because arrays are of typeobject. - When we iterate over
[0]in that call of removeNull(),kstarts as0(the index in the array), andobj[k]becomes0(the value).0passestypeof 0 !== 'boolean' && !0 && 0 !== undefined, so it getsdeletedand turned into an empty item in the array.deleteempties out array elements but doesn't remove the index.
There might be some ways to reorganize the code to make it a little safer and easier to debug, depending on whether you want to remove null in arrays, too.
let data = {
title:"hello world", // not removed
value: [
0, // not removed
null // removed
],
name: null, // removed
author: {
name: null, // removed
hats: false, // not removed
pets: [null] // --> []
partners: [] // --> []
}
}
const sanitized = removeNull(data);
console.log(sanitized)
// -----------------------------------------------------------------------
function removeNull(obj) {
Object.keys(obj).forEach((key) => {
if(obj[key] === null) {
// removes the element differently
// depending on whether obj is array or object.
return Array.isArray(obj) ? obj.splice(key, 1) : delete obj[key]
}
if(typeof obj[key] === 'object') removeNull(obj[key])
})
return obj
}
If you don't care about checking for null in arrays, add && !Array.isArray(obj) to the second check, and remove the ternary that decides how to delete.
One note: in addition to returning the new null-less object, this code (and your code) currently also modify the original object.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Allxie |
