Skip to content

Commit

Permalink
feat: Add row object iterator support.
Browse files Browse the repository at this point in the history
  • Loading branch information
jheer committed Sep 26, 2020
1 parent 2399218 commit 7161e19
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 9 deletions.
30 changes: 22 additions & 8 deletions src/table/column-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import toMarkdown from '../format/to-markdown';
import arrayType from '../util/array-type';
import error from '../util/error';
import mapObject from '../util/map-object';
import unroll from '../util/unroll';
import rowObjectBuilder from '../util/row-object-builder';

/**
* Class representing a table backed by a named set of columns.
Expand Down Expand Up @@ -113,14 +113,8 @@ export default class ColumnTable extends Table {
objects(options = {}) {
const limit = numRows(this, options.limit);
if (limit <= 0) return [];

const tuples = Array(limit);
const names = this.columnNames();
const create = unroll(
names.map(name => this.column(name)),
'row',
'({' + names.map((_, i) => `${JSON.stringify(_)}:_${i}.get(row)`) + '})'
);
const create = rowObjectBuilder(this);

let r = 0;
this.scan((row, data, stop) => {
Expand All @@ -131,6 +125,26 @@ export default class ColumnTable extends Table {
return tuples;
}

/**
* Returns an iterator over objects representing table rows.
* @return {Iterator} An iterator over row objects.
*/
*[Symbol.iterator]() {
const create = rowObjectBuilder(this);
const n = this.numRows();

if (this.isOrdered() || this.isFiltered) {
const indices = this.indices();
for (let i = 0; i < n; ++i) {
yield create(indices[i]);
}
} else {
for (let i = 0; i < n; ++i) {
yield create(i);
}
}
}

/**
* Create a new fully-materialized instance of this table.
* All filter and orderby settings are removed from the new table.
Expand Down
10 changes: 9 additions & 1 deletion src/table/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ export default class Table {
error('Not implemented');
}

/**
* Returns an iterator over objects representing table rows.
* @return {Iterator} An iterator over row objects.
*/
[Symbol.iterator]() {
error('Not implemented');
}

/**
* Print the contents of this table using the console.table() method.
* @param {ObjectsOptions} options The options for row object generation,
Expand Down Expand Up @@ -350,7 +358,7 @@ export default class Table {
const stop = () => i = this._total;

if (order && this.isOrdered() || filter && this._index) {
const index = this._index = this.indices();
const index = this.indices();
const data = this._data;
for (; i < nrows; ++i) {
fn(index[i], data, stop);
Expand Down
10 changes: 10 additions & 0 deletions src/util/row-object-builder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import unroll from './unroll';

export default function(table, names) {
names = names || table.columnNames();
return unroll(
names.map(name => table.column(name)),
'row',
'({' + names.map((_, i) => `${JSON.stringify(_)}:_${i}.get(row)`) + '})'
);
}
24 changes: 24 additions & 0 deletions test/table/column-table-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,30 @@ tape('ColumnTable supports object output', t => {
t.end();
});

tape('ColumnTable supports iterator output', t => {
const output = [
{ u: 'a', v: 2 },
{ u: 'a', v: 1 },
{ u: 'a', v: 4 },
{ u: 'b', v: 5 },
{ u: 'b', v: 3 }
];

const dt = new ColumnTable({
u: ['a', 'a', 'a', 'b', 'b'],
v: [2, 1, 4, 5, 3]
});

t.deepEqual([...dt], output, 'iterator data');
t.deepEqual(
[...dt.orderby('v')],
output.slice().sort((a, b) => a.v - b.v),
'iterator data orderby'
);

t.end();
});

tape('ColumnTable toString shows table state', t => {
const dt = new ColumnTable({
a: ['a', 'a', 'a', 'b', 'b'],
Expand Down

0 comments on commit 7161e19

Please sign in to comment.