UNPKG

1.95 kBJavaScriptView Raw
1import {fieldNames} from './util/util';
2import {Transform, ingest, rederive, tupleid} from 'vega-dataflow';
3import {inherits} from 'vega-util';
4
5/**
6 * Performs a relational projection, copying selected fields from source
7 * tuples to a new set of derived tuples.
8 * @constructor
9 * @param {object} params - The parameters for this operator.
10 * @param {Array<function(object): *} params.fields - The fields to project,
11 * as an array of field accessors. If unspecified, all fields will be
12 * copied with names unchanged.
13 * @param {Array<string>} [params.as] - Output field names for each projected
14 * field. Any unspecified fields will use the field name provided by
15 * the field accessor.
16 */
17export default function Project(params) {
18 Transform.call(this, null, params);
19}
20
21Project.Definition = {
22 'type': 'Project',
23 'metadata': {'generates': true, 'changes': true},
24 'params': [
25 { 'name': 'fields', 'type': 'field', 'array': true },
26 { 'name': 'as', 'type': 'string', 'null': true, 'array': true }
27 ]
28};
29
30inherits(Project, Transform, {
31 transform(_, pulse) {
32 const out = pulse.fork(pulse.NO_SOURCE),
33 fields = _.fields,
34 as = fieldNames(_.fields, _.as || []),
35 derive = fields
36 ? (s, t) => project(s, t, fields, as)
37 : rederive;
38
39 let lut;
40 if (this.value) {
41 lut = this.value;
42 } else {
43 pulse = pulse.addAll();
44 lut = this.value = {};
45 }
46
47 pulse.visit(pulse.REM, t => {
48 const id = tupleid(t);
49 out.rem.push(lut[id]);
50 lut[id] = null;
51 });
52
53 pulse.visit(pulse.ADD, t => {
54 const dt = derive(t, ingest({}));
55 lut[tupleid(t)] = dt;
56 out.add.push(dt);
57 });
58
59 pulse.visit(pulse.MOD, t => {
60 out.mod.push(derive(t, lut[tupleid(t)]));
61 });
62
63 return out;
64 }
65});
66
67function project(s, t, fields, as) {
68 for (let i=0, n=fields.length; i<n; ++i) {
69 t[as[i]] = fields[i](s);
70 }
71 return t;
72}