Skip to content

Commit

Permalink
feat: Add rename verb. (#150)
Browse files Browse the repository at this point in the history
  • Loading branch information
jheer committed Apr 23, 2021
1 parent eca57dd commit 577b076
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 12 deletions.
31 changes: 30 additions & 1 deletion docs/api/verbs.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ title: Verbs \| Arquero API Reference
* [orderby](#orderby), [unorder](#unorder)
* [rollup](#rollup), [count](#count)
* [sample](#sample)
* [select](#select), [relocate](#relocate)
* [select](#select), [relocate](#relocate), [rename](#rename)
* [reify](#reify)
* [Join Verbs](#joins)
* [cross](#cross)
Expand Down Expand Up @@ -273,6 +273,35 @@ table.relocate({ colA: 'newA', colB: 'newB' }, { after: 'colC' })
```


<hr/><a id="rename" href="#rename">#</a>
<em>table</em>.<b>rename</b>(<i>columns</i>) · [Source](https://github.com/uwdata/arquero/blob/master/src/verbs/rename.js)

Rename one or more columns, preserving column order.

* *columns*: One or more rename objects with current column names as keys and new column names as values.

*Examples*

```js
// rename colA to colA2
table.rename({ colA: 'colA2' })
```

```js
// rename 'old col' to 'new col'
table.rename({ 'old col': 'new col' })
```

```js
// rename colA and colB
table.rename({ colA: 'colA2', colB: 'colB2' })
```

```js
// rename colA and colB, alternate syntax
table.rename({ colA: 'colA2' }, { colB: 'colB2' })
```

<hr/><a id="reify" href="#reify">#</a>
<em>table</em>.<b>reify</b>([<i>indices</i>]) · [Source](https://github.com/uwdata/arquero/blob/master/src/table/column-table.js)

Expand Down
3 changes: 3 additions & 0 deletions src/query/verb.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ export const Verbs = {
props: { before: SelectionList, after: SelectionList }
}
]),
rename: createVerb('rename', [
{ name: 'columns', type: SelectionList }
]),
rollup: createVerb('rollup', [
{ name: 'values', type: ExprObject }
]),
Expand Down
12 changes: 12 additions & 0 deletions src/table/transformable.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ export default class Transformable {
return this.__relocate(this, toArray(columns), options);
}

/**
* Rename one or more columns, preserving column order.
* @param {...Select} columns One or more rename objects with current
* column names as keys and new column names as values.
* @return {this} A new table with renamed columns.
* @example table.rename({ oldName: 'newName' })
* @example table.rename({ a: 'a2', b: 'b2' })
*/
rename(...columns) {
return this.__rename(this, columns.flat());
}

/**
* Rollup a table to produce an aggregate summary.
* Often used in conjunction with {@link Transformable#groupby}.
Expand Down
2 changes: 2 additions & 0 deletions src/verbs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import __semijoin from './join-filter';
import __lookup from './lookup';
import __pivot from './pivot';
import __relocate from './relocate';
import __rename from './rename';
import __rollup from './rollup';
import __sample from './sample';
import __select from './select';
Expand Down Expand Up @@ -47,6 +48,7 @@ export default {
__lookup,
__pivot,
__relocate,
__rename,
__rollup,
__sample,
__select,
Expand Down
8 changes: 8 additions & 0 deletions src/verbs/rename.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import _select from '../engine/select';
import resolve from '../helpers/selection';

export default function(table, columns) {
const map = new Map();
table.columnNames(x => (map.set(x, x), 0));
return _select(table, resolve(table, columns, map));
}
36 changes: 27 additions & 9 deletions test/query/query-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { field, func } from './util';
const {
count, dedupe, derive, filter, groupby, orderby,
reify, rollup, select, sample, ungroup, unorder,
relocate, impute, fold, pivot, spread, unroll,
relocate, rename, impute, fold, pivot, spread, unroll,
cross, join, semijoin, antijoin,
concat, union, except, intersect
} = Verbs;
Expand Down Expand Up @@ -429,6 +429,24 @@ tape('Query evaluates orderby verbs', t => {
t.end();
});

tape('Query evaluates reify verbs', t => {
const dt = table({
foo: [0, 1, 2, 3],
bar: [1, 1, 0, 0]
}).filter(d => d.foo < 1);

tableEqual(
t,
Query.from(
new Query([ reify() ]).toObject()
).evaluate(dt),
{ foo: [0], bar: [1] },
'reify query result'
);

t.end();
});

tape('Query evaluates relocate verbs', t => {
const a = [1], b = [2], c = [3], d = [4];
const dt = table({ a, b, c, d });
Expand Down Expand Up @@ -458,19 +476,19 @@ tape('Query evaluates relocate verbs', t => {
t.end();
});

tape('Query evaluates reify verbs', t => {
const dt = table({
foo: [0, 1, 2, 3],
bar: [1, 1, 0, 0]
}).filter(d => d.foo < 1);
tape('Query evaluates rename verbs', t => {
const a = [1], b = [2], c = [3], d = [4];
const dt = table({ a, b, c, d });

tableEqual(
t,
Query.from(
new Query([ reify() ]).toObject()
new Query([
rename({ d: 'w', a: 'z' })
]).toObject()
).evaluate(dt),
{ foo: [0], bar: [1] },
'reify query result'
{ z: a, b, c, w: d },
'rename query result'
);

t.end();
Expand Down
24 changes: 23 additions & 1 deletion test/query/verb-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { field, func } from './util';
const {
count, dedupe, derive, filter, groupby, orderby,
reify, rollup, sample, select, ungroup, unorder,
relocate, impute, pivot, unroll, join, concat
relocate, rename, impute, pivot, unroll, join, concat
} = Verbs;

function test(t, verb, expect, msg) {
Expand Down Expand Up @@ -215,6 +215,28 @@ tape('relocate verb serializes to object', t => {
t.end();
});

tape('rename verb serializes to object', t => {
test(t,
rename([{ foo: 'bar' }]),
{
verb: 'rename',
columns: [{ foo: 'bar' }]
},
'serialized rename verb'
);

test(t,
rename([{ foo: 'bar' }, { baz: 'bop' }]),
{
verb: 'rename',
columns: [{ foo: 'bar' }, { baz: 'bop' }]
},
'serialized rename verb'
);

t.end();
});

tape('rollup verb serializes to object', t => {
const verb = rollup({
count: op.count(),
Expand Down
31 changes: 30 additions & 1 deletion test/query/verb-to-ast-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
const {
count, dedupe, derive, filter, groupby, orderby,
reify, rollup, sample, select, ungroup, unorder,
relocate, impute, pivot, unroll, join, concat
relocate, rename, impute, pivot, unroll, join, concat
} = Verbs;

function toAST(verb) {
Expand Down Expand Up @@ -296,6 +296,35 @@ tape('relocate verb serializes to AST', t => {
t.end();
});

tape('rename verb serializes to AST', t => {
t.deepEqual(
toAST(rename([{ foo: 'bar' }])),
{
type: 'Verb',
verb: 'rename',
columns: [
{ type: 'Column', name: 'foo', as: 'bar' }
]
},
'ast rename verb'
);

t.deepEqual(
toAST(rename([{ foo: 'bar' }, { baz: 'bop' }])),
{
type: 'Verb',
verb: 'rename',
columns: [
{ type: 'Column', name: 'foo', as: 'bar' },
{ type: 'Column', name: 'baz', as: 'bop' }
]
},
'ast rename verb'
);

t.end();
});

tape('rollup verb serializes to AST', t => {
const verb = rollup({
count: op.count(),
Expand Down
49 changes: 49 additions & 0 deletions test/verbs/rename-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import tape from 'tape';
import tableEqual from '../table-equal';
import { table } from '../../src';

tape('rename renames columns', t => {
const data = {
a: [1, 3, 5, 7],
b: [2, 4, 6, 8],
c: 'abcd'.split('')
};

tableEqual(t,
table(data).rename({ a: 'z'}),
{ z: data.a, b: data.b, c: data.c },
'renamed data, single column'
);

tableEqual(t,
table(data).rename({ a: 'z', b: 'y' }),
{ z: data.a, y: data.b, c: data.c },
'renamed data, multiple columns'
);

t.deepEqual(
table(data).rename({ a: 'z', c: 'x' }).columnNames(),
['z', 'b', 'x'],
'renamed data, preserves order'
);

tableEqual(t,
table(data).rename('a', 'b'),
data,
'renamed data, no rename'
);

tableEqual(t,
table(data).rename(),
data,
'renamed data, no arguments'
);

tableEqual(t,
table(data).rename({ a: 'z'}, { c: 'x' }),
{ z: data.a, b: data.b, x: data.c },
'renamed data, multiple arguments'
);

t.end();
});

0 comments on commit 577b076

Please sign in to comment.