prototype.batchTransform = function(input, data) { log.debug(input, ['treeifying']); var fields = this.param('groupby').field, childField = this._output.children, parentField = this._output.parent, summary = [{name:'*', ops: ['values'], as: [childField]}], aggrs = fields.map(function(f) { return dl.groupby(f).summarize(summary); }), prev = this._internal || [], curr = [], i, n; function level(index, node, values) { var vals = aggrs[index].execute(values); node[childField] = vals; vals.forEach(function(n) { n[parentField] = node; curr.push(Tuple.ingest(n)); if (index+1 < fields.length) level(index+1, n, n[childField]); else n[childField].forEach(function(c) { c[parentField] = n; }); }); } var root = Tuple.ingest({}); root[parentField] = null; curr.push(root); level(0, root, data); // update changeset with internal nodes for (i=0, n=curr.length; i<n; ++i) { input.add.push(curr[i]); } for (i=0, n=prev.length; i<n; ++i) { input.rem.push(prev[i]); } this._internal = curr; return input; };
function tuple(gb, gv, ob, ov) { var t = {_imputed: true}, i; for (i=0; i<gv.length; ++i) t[gb[i]] = gv[i]; for (i=0; i<ov.length; ++i) t[ob[i]] = ov[i]; return Tuple.ingest(t); }
vals.forEach(function(n) { n[parentField] = node; curr.push(Tuple.ingest(n)); if (index+1 < fields.length) level(index+1, n, n[childField]); else n[childField].forEach(function(c) { c[parentField] = n; }); });