Unflatten a JSON object (v2)

Revision 2 of this benchmark created by Aadit M Shah on


Preparation HTML

<script>
var object = {
    "foo[0].bar": true,
    "foo[1].baz": false
};

function controlUnflatten(data) {
    if (Object(data) !== data || Array.isArray(data))
        return data;
    var regex = /\.?([^.\[\]]+)$|\[(\d+)\]$/,
        result;
    /* EcmaScript 5.1 §12.6.4:
    > If new properties are added to the object being enumerated during
    > enumeration, the newly added properties _are_not_guaranteed_ to be visited
    > in the active enumeration
    Therefore wrapping in a while-loop: */
    while (Object.keys(data).length)
    for (var p in data) {
        var m = regex.exec(p),
            target;
        if (m.index) {
            var rest = p.slice(0, m.index);
            target = data[rest] || (data[rest] = (m[2] ? [] : {}));
        } else {
            target = result || (result = (m[2] ? [] : {}));
        }
        target[m[2] || m[1]] = data[p];
        delete data[p];
    }
    return result;
}

var testUnflatten = (function (regex) {
    return function (table) {
        var accumulator = {}, stack = [];

        for (var path in table) {
            accumulator[path] = table[path];
            stack.push(path);
        }

        var template = regex, result;

        while (stack.length) {
            var path = stack.shift(), match = template.exec(path), index = match.index, array = match[1];
            if (index) var address = path.slice(0, index), cursor = accumulator[address] ||
                (accumulator[address] = (stack.push(address), array ? [] : {}));
            else var cursor = result || (result = array ? [] : {});
            cursor[array || match[2]] = accumulator[path];
        }

        return result;
    };
}(/\[(\d+)\]$|\.?([^.\[\]]+)$/));
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Test unflatten
testUnflatten(object);
ready
Control unflatten
controlUnflatten(object);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.

  • Revision 1: published by Aadit M Shah on
  • Revision 2: published by Aadit M Shah on
  • Revision 3: published by Robert Koritnik on