1+ import { bisectOffsets } from './util.js' ;
2+
13/**
24 * A table consists of a collection of named columns (or 'children').
35 * To work with table data directly in JavaScript, usse `toColumns()`
@@ -110,42 +112,57 @@ export class Table {
110112 return cols ;
111113 }
112114
115+ /**
116+ * Return an array of objects representing the rows of this table.
117+ * @returns {Record<string, any>[] }
118+ */
119+ toArray ( ) {
120+ const { children, numRows, names } = this ;
121+ const data = children [ 0 ] ?. data ?? [ ] ;
122+ const output = Array ( numRows ) ;
123+ for ( let b = 0 , row = - 1 ; b < data . length ; ++ b ) {
124+ for ( let i = 0 ; i < data [ b ] . length ; ++ i ) {
125+ output [ ++ row ] = rowObject ( names , children , b , i ) ;
126+ }
127+ }
128+ return output ;
129+ }
130+
113131 /**
114132 * Return an iterator over objects representing the rows of this table.
115133 * @returns {Generator<Record<string, any>, any, null> }
116134 */
117135 * [ Symbol . iterator ] ( ) {
118136 const { children, names } = this ;
119- const batches = children [ 0 ] ?. data . length ?? 0 ;
120- // for each batch...
121- for ( let b = 0 ; b < batches ; ++ b ) {
122- const data = children . map ( c => c . data [ b ] ) ;
123- const rows = data [ 0 ] . length ;
124- // for each row...
125- for ( let i = 0 ; i < rows ; ++ i ) {
126- yield rowObject ( names , data , i ) ;
137+ const data = children [ 0 ] ?. data ?? [ ] ;
138+ for ( let b = 0 ; b < data . length ; ++ b ) {
139+ for ( let i = 0 ; i < data [ b ] . length ; ++ i ) {
140+ yield rowObject ( names , children , b , i ) ;
127141 }
128142 }
129143 }
130144
131145 /**
132- * Return an array of objects representing the rows of this table.
133- * @returns {Record<string, any>[] }
146+ * Return a row object for the given index.
147+ * @param {number } index The row index.
148+ * @returns {Record<string, any> } The row object.
134149 */
135- toArray ( ) {
136- const { children, numRows, names } = this ;
137- const batches = children [ 0 ] ?. data . length ?? 0 ;
138- const output = Array ( numRows ) ;
139- // for each batch...
140- for ( let b = 0 , row = - 1 ; b < batches ; ++ b ) {
141- const data = children . map ( c => c . data [ b ] ) ;
142- const rows = data ?. [ 0 ] . length ;
143- // for each row...
144- for ( let i = 0 ; i < rows ; ++ i ) {
145- output [ ++ row ] = rowObject ( names , data , i ) ;
146- }
147- }
148- return output ;
150+ at ( index ) {
151+ const { names, children, numRows } = this ;
152+ if ( index < 0 || index >= numRows ) return null ;
153+ const [ { offsets } ] = children ;
154+ const i = bisectOffsets ( offsets , index ) ;
155+ return rowObject ( names , children , i , index - offsets [ i ] ) ;
156+ }
157+
158+ /**
159+ * Return a row object for the given index. This method is the same as
160+ * `at()` and is provided for better compatibility with Apache Arrow JS.
161+ * @param {number } index The row index.
162+ * @returns {Record<string, any> } The row object.
163+ */
164+ get ( index ) {
165+ return this . at ( index ) ;
149166 }
150167}
151168
@@ -155,11 +172,10 @@ function renameField(field, name) {
155172 : field ;
156173}
157174
158- function rowObject ( names , data , index ) {
175+ function rowObject ( names , children , batch , index ) {
159176 const o = { } ;
160- // for each column...
161177 for ( let j = 0 ; j < names . length ; ++ j ) {
162- o [ names [ j ] ] = data [ j ] . at ( index ) ;
178+ o [ names [ j ] ] = children [ j ] . data [ batch ] . at ( index ) ;
163179 }
164180 return o ;
165181}
0 commit comments