-
-
Save jed/1111672 to your computer and use it in GitHub Desktop.
replacer = (key, val) -> | |
if val instanceof Object | |
keys = Object.keys(val).sort().map (key) -> | |
"\"#{key}\":#{JSON.stringify val[key], replacer}" | |
"{#{keys}}" | |
else val |
The following works for me, do you see any potential problems with it? Tested it with deeply nested objects, so far never broke.
replacer = (key, value) ->
return value unless value.constructor is Object
Object.keys(value).sort().reduce (sorted, key) ->
sorted[key] = value[key]
sorted
, {}
@ncr, this still relies on order of insertion. try it with {1a: 1, 22: 1}
on v8 and you'll get {"22":1,"1a":1}
.
@jed the quirk with keys that are parseable as 32bit integers is actually not a problem in my case - I use this code in v8 only, so the key here is not the actual "sorting" but the stability of returned results.
I use this function to ensure that a stringified JSON looks always identical for a given equivalent data so I can sign it.
indeed, assuming v8 doesn't change their iteration implementation. i like the use of reduce
too (though not a huge fan of coffee syntax for arguments following functions).
@ncr Thanks, that worked for me, but had to add a null
check. In regular JS:
function replacer (key, value) {
if (value == null || value.constructor != Object) {
return value
}
return Object.keys(value).sort().reduce((s,k) => {s[k] = value[k]; return s}, {})
}
Thanks for the midday diversion. Let me know if you come up with something workable.