-
-
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 |
Thanks for the midday diversion. Let me know if you come up with something workable.
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}, {})
}
@polotek,
wow, thanks for the thoughtful answer! yeah, i think this is a no-go. best bet would probably return a new object with keys defined in order and hope the engine respects it (which of course it's not required to).
oh, and next time i'll write in in JS for ya, heh.