UNPKG

arquero

Version:

Query processing and transformation of array-backed data tables.

51 lines (44 loc) 1.62 kB
import { not } from '../helpers/selection.js'; import { columnSet } from '../table/ColumnSet.js'; import { concat } from '../util/concat.js'; import { NULL } from '../util/null.js'; import { unroll } from '../util/unroll.js'; import { rowLookup } from './join/lookup.js'; import { aggregateGet } from './reduce/util.js'; import { inferKeys } from './util/join-keys.js'; import { parseKey } from './util/parse-key.js'; import { parseValue } from './util/parse.js'; export function lookup(tableL, tableR, on, ...values) { on = inferKeys(tableL, tableR, on); values = values.length === 0 ? [not(tableL.columnNames())] : values.flat(); return _lookup( tableL, tableR, [ parseKey('lookup', tableL, on[0]), parseKey('lookup', tableR, on[1]) ], parseValue('lookup', tableR, values) ); } export function _lookup(tableL, tableR, [keyL, keyR], { names, exprs, ops = [] }) { // instantiate output data const cols = columnSet(tableL); const total = tableL.totalRows(); names.forEach(name => cols.add(name, Array(total).fill(NULL))); // build lookup table const lut = rowLookup(tableR, keyR); // generate setter function for lookup match const set = unroll( ['lr', 'rr', 'data'], '{' + concat(names, (_, i) => `_[${i}][lr] = $[${i}](rr, data);`) + '}', names.map(name => cols.data[name]), aggregateGet(tableR, ops, exprs) ); // find matching rows, set values on match const dataR = tableR.data(); tableL.scan((lrow, data) => { const rrow = lut.get(keyL(lrow, data)); if (rrow >= 0) set(lrow, rrow, dataR); }); return cols.derive(tableL); }