Where developers come to connect, share, build and be inspired.

6

Deterministic JSON.stringify()

1661 views

Using JavaScript objects as generic maps can be difficult, especially if you want to use objects as keys, because map keys are required to be (or are converted to) strings. Objects can be converted to strings using JSON.stringify(), but the ordering of keys is not guaranteed here, which means the same (or equivalent) objects can result in different strings.

These functions provide a way to serialize and deserialize objects deterministically by converting them to key-value pairs, sorting those pairs by key, then passing them through JSON.stringify(). This code requires Underscore.js.

Stringify:

function stringify(obj) {
  function flatten(obj) {
    if (_.isObject(obj)) {
      return _.sortBy(_.map(
          _.pairs(obj),
          function(p) { return [p[0], flatten(p[1])]; }
        ),
        function(p) { return p[0]; }
      );
    }
    return obj;
  }
  return JSON.stringify(flatten(obj));
}

Parse:

function parse(str) {
  function inflate(obj, pairs) {
     _.each(pairs, function(p) {
      obj[p[0]] = _.isArray(p[1]) ?
        inflate({}, p[1]) :
        p[1];
    });
    return obj;
  }
  return inflate({}, JSON.parse(str));
}

Comments

Add a comment