-
-
Save davidfurlong/463a83a33b70a3b6618e97ec9679e490 to your computer and use it in GitHub Desktop.
// Spec http://www.ecma-international.org/ecma-262/6.0/#sec-json.stringify | |
const replacer = (key, value) => | |
value instanceof Object && !(value instanceof Array) ? | |
Object.keys(value) | |
.sort() | |
.reduce((sorted, key) => { | |
sorted[key] = value[key]; | |
return sorted | |
}, {}) : | |
value; | |
// Usage | |
// JSON.stringify({c: 1, a: { d: 0, c: 1, e: {a: 0, 1: 4}}}, replacer); |
Ingenious!
Excellent!
Now my getUniqueObjects function works correctly.
function getUniqueObjects(arr) {
const replacer = (key, value) =>
value && typeof value === "object" && !Array.isArray(value)
? Object.keys(value)
.sort()
.reduce((sorted, key) => {
sorted[key] = value[key];
return sorted;
}, {})
: value;
return arr.filter(
(v, i, a) =>
a.findIndex(
(v2) => JSON.stringify(v2, replacer) === JSON.stringify(v, replacer)
) === i
);
}
It fails to handle the fundamental Object types, converting number, boolean, etc into object...
JSON.stringify({c: new Number(1), a: { d: 0, c: 1, e: {a: 0, 1: 4}}}, replacer,2);
'{\n' +
' "a": {\n' +
' "c": 1,\n' +
' "d": 0,\n' +
' "e": {\n' +
' "1": 4,\n' +
' "a": 0\n' +
' }\n' +
' },\n' +
' "c": {}\n' + <<<<===== OOPS!
'}'
const replacer = (key, value) =>
value instanceof Object && !(value instanceof Array) && !(value instanceof Function) && !(value instanceof Date) && !(value instanceof RegExp) && !(value instanceof Boolean) && !(value instanceof Number) && !(value instanceof String) ?
Object.keys(value)
.sort()
.reduce((sorted, key) => {
sorted[key] = value[key];
return sorted
}, {}) :
value;
It fails to handle the fundamental Object types, converting number, boolean, etc into object...
JSON.stringify({c: new Number(1), a: { d: 0, c: 1, e: {a: 0, 1: 4}}}, replacer,2); '{\n' + ' "a": {\n' + ' "c": 1,\n' + ' "d": 0,\n' + ' "e": {\n' + ' "1": 4,\n' + ' "a": 0\n' + ' }\n' + ' },\n' + ' "c": {}\n' + <<<<===== OOPS! '}'
const replacer = (key, value) => value instanceof Object && !(value instanceof Array) && !(value instanceof Function) && !(value instanceof Date) && !(value instanceof RegExp) && !(value instanceof Boolean) && !(value instanceof Number) && !(value instanceof String) ? Object.keys(value) .sort() .reduce((sorted, key) => { sorted[key] = value[key]; return sorted }, {}) : value;
@bcowgill A nice edge case! What about using this expression
value instanceof Object && !Array.isArray(value) && Object.keys(value).length > 0
to make it more succinct?
This is quite clever. Touche.