Skip to content

Instantly share code, notes, and snippets.

@Jerska
Last active December 19, 2019 10:11
Show Gist options
  • Save Jerska/11bd6a8e7c19521ffa20afc65e21b96c to your computer and use it in GitHub Desktop.
Save Jerska/11bd6a8e7c19521ffa20afc65e21b96c to your computer and use it in GitHub Desktop.
Stable JSON stringify
// Make sure JSON keys are always in the same order, to allow for easy comparison
// This uses JSON.stringify's replacer twice:
// - once to get the list of keys, including of nested children
// - once in its lesser known form: as a array of keys
// this filters keys to only ones in the list - (we don't use this feature)
// but also sorts them, and this is why this is useful to us
export function stableJSONStringify(obj: any) {
const allKeys: string[] = [];
// Use the replacer function to get the keys
JSON.stringify(obj, (k, v) => {
if (k !== '') allKeys.push(k);
return v;
});
// Sorted and unique list of keys
const uniqueKeys = allKeys.filter((k, i) => allKeys.indexOf(k) === i);
const sortedKeys = uniqueKeys.sort();
// Use the "filter" behavior (that also sorts keys in the order provided)
// of the replacer parameter of JSON.stringify to ensure a stable stringification
return JSON.stringify(obj, sortedKeys);
}
import { stableJSONStringify } from './stableJSONStringify';
// Numbers are used as values and are used to represent the order they should be showing up in the output
describe('stableJSONStringify', () => {
it('should sort keys', () => {
const obj = {
b: 2,
a: 1,
};
expect(stableJSONStringify(obj)).toMatchSnapshot();
});
it('should sort nested keys', () => {
const obj = {
b: 3,
a: {
d: 2,
c: 1,
},
};
expect(stableJSONStringify(obj)).toMatchSnapshot();
});
it('should sort nested keys in an array', () => {
const obj = {
b: 3,
a: [
{
d: 2,
c: 1,
},
],
};
expect(stableJSONStringify(obj)).toMatchSnapshot();
});
});
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`stableJSONStringify should sort keys 1`] = `"{\\"a\\":1,\\"b\\":2}"`;
exports[`stableJSONStringify should sort nested keys 1`] = `"{\\"a\\":{\\"c\\":1,\\"d\\":2},\\"b\\":3}"`;
exports[`stableJSONStringify should sort nested keys in an array 1`] = `"{\\"a\\":[{\\"c\\":1,\\"d\\":2}],\\"b\\":3}"`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment