I want to keep all property names that start with a certain string and remove all others from an object.
Why is the following not working – keep property foo
only – and why does the opposite work? (test it here):
const o = {
foo: 1,
bar: 2,
baz: 3
};
console.log(JSON.stringify(o, (k, v) => k.startsWith('f') ? v : undefined)); // undefined -> why not {"foo":1} ?
console.log(JSON.stringify(o, (k, v) => !k.startsWith('f') ? undefined : v)); // undefined -> why not {"foo":1} ?
console.log(JSON.stringify(o, (k, v) => !k.startsWith('f') ? v : undefined)); // {"bar":2,"baz":3}
Object.keys(o).forEach(key => {
console.log(key, key.startsWith('f'));
});
// foo,true
// bar,false
// baz,false
2
Answers
You need to handle the empty key passed to the replacer function.
According to the documentation,
So that when you return an
undefined
value for the first entry, the stringified result isundefined
.Reading the docs of
JSON.stringify
And in your first two calls of JSON stringify, you return
undefined
when thekey
does not start withf
(which is obviously the case, whenkey == ""
). And so if the replacer for the initial object returnsundefined
, of course the result the whole stringification isundefined