JavaScript: JSON.stringify and replacer, Unexpected behavior

31 Views Asked by At

Consider the following code

'use strict'; 

function stringify(value,p) {
    function replacer(k,v) {
        if (!Array.isArray(v))
            return p(k) ? v : undefined;
        return v
    }
    return JSON.stringify(value,replacer);
}

console.log(stringify([{ city: 'Milano', air_quality: 'red', temperature: 10 }, { air_quality: 'yellow', 'temperature': 20, 'sea_conditions': 3, city: 'Genova' }], k => k.match(/^[a-z]+$/)));
console.log(stringify([{ city: 'Milano', air_quality: 'red', temperature: 10 }, { air_quality: 'yellow', 'temperature': 20, 'sea_conditions': 3, city: 'Genova' }], k => k.length < 5));

i'm expecting the following output

[{"city":"Milano","temperature":10},{"temperature":20,"city":"Genova"}]
[{"city":"Milano"},{"city":"Genova"}]

but i'm obtaining

[null,null]
[{"city":"Milano"},{"city":"Genova"}]

so basically it works for the second input but not for the first one, and i absolutely can't explain why, the only thing that changes is the predicate used!

i know that with the following replacer

 function replacer(k,v){
        if (typeof v === 'object' && !Array.isArray(v)) {
            let result = {}
            for (let idx in v) {
                if(p(idx)) {
                    result[idx] = v[idx]
                }
            }
            return result
        }
        return v
    }

everything will work as expected, but can someone explain me why in the first version it worked on one input and not on the other?

1

There are 1 best solutions below

2
Pointy On

The keys in the outer array you pass to your stringify() function are 0 and 1. Neither of those match the regex (which looks for letters), so the values in the result are null (because undefined cannot be represented in JSON).