Skip to content

Instantly share code, notes, and snippets.

@klaasman
Created March 10, 2015 14:19
Show Gist options
  • Save klaasman/a5f6edf66be928655181 to your computer and use it in GitHub Desktop.
Save klaasman/a5f6edf66be928655181 to your computer and use it in GitHub Desktop.
Json stable stringify - amd ready
define(function () {
'use strict';
return function (obj, opts) {
if (!opts) {
opts = {};
}
if (typeof opts === 'function') {
opts = { cmp: opts };
}
var space = opts.space || '';
if (typeof space === 'number') {
space = new Array(space+1).join(' ');
}
var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;
var replacer = opts.replacer || function(key, value) { return value; };
var cmp = opts.cmp && (function (f) {
return function (node) {
return function (a, b) {
var aobj = { key: a, value: node[a] };
var bobj = { key: b, value: node[b] };
return f(aobj, bobj);
};
};
})(opts.cmp);
var seen = [];
return (function stringify (parent, key, node, level) {
/*jshint maxcomplexity: 12 */
var indent = space ? ('\n' + new Array(level + 1).join(space)) : '';
var colonSeparator = space ? ': ' : ':';
var out = [];
if (node && node.toJSON && typeof node.toJSON === 'function') {
node = node.toJSON();
}
node = replacer.call(parent, key, node);
if (node === undefined) {
return;
}
if (typeof node !== 'object' || node === null) {
return JSON.stringify(node);
}
if (Array.isArray(node)) {
node.forEach(function (curNode, index) {
var item = stringify(node, index, curNode, level + 1) || JSON.stringify(null);
out.push(indent + space + item);
});
return '[' + out.join(',') + indent + ']';
} else {
if (seen.indexOf(node) !== -1) {
if (cycles) {
return JSON.stringify('__cycle__');
}
throw new TypeError('Converting circular structure to JSON');
} else {
seen.push(node);
}
Object
.keys(node)
.sort(cmp && cmp(node))
.forEach(function (key) {
var value = stringify(node, key, node[key], level+1);
if (value) {
var keyValue = JSON.stringify(key) + colonSeparator + value;
out.push(indent + space + keyValue);
}
});
return '{' + out.join(',') + indent + '}';
}
})({ '': obj }, '', obj, 0);
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment