| 322 | } |
| 323 | |
| 324 | public groupBy<U>(key: ArrayFunc<T, U>, comparator?: ArrayComparator<U>): DataArray<{ key: U; rows: T[] }> { |
| 325 | if (this.values.length == 0) return this.lwrap([]); |
| 326 | |
| 327 | // JavaScript sucks and we can't make hash maps over arbitrary types (only strings/ints), so |
| 328 | // we do a poor man algorithm where we SORT, followed by grouping. |
| 329 | let intermediate = this.sort(key, "asc", comparator); |
| 330 | comparator = comparator ?? this.defaultComparator; |
| 331 | |
| 332 | let result: { key: U; rows: T[] }[] = []; |
| 333 | let currentRow = [intermediate[0]]; |
| 334 | let current = key(intermediate[0], 0, (intermediate as DataArrayImpl<T>).values); |
| 335 | for (let index = 1; index < intermediate.length; index++) { |
| 336 | let newKey = key(intermediate[index], index, (intermediate as DataArrayImpl<T>).values); |
| 337 | if (comparator(current, newKey) != 0) { |
| 338 | result.push({ key: current, rows: currentRow }); |
| 339 | current = newKey; |
| 340 | currentRow = [intermediate[index]]; |
| 341 | } else { |
| 342 | currentRow.push(intermediate[index]); |
| 343 | } |
| 344 | } |
| 345 | result.push({ key: current, rows: currentRow }); |
| 346 | |
| 347 | return this.lwrap(result); |
| 348 | } |
| 349 | |
| 350 | public groupIn<U>(key: ArrayFunc<LowestKey<T>, U>, comparator?: ArrayComparator<U>): DataArray<Ingrouped<U, T>> { |
| 351 | if (Groupings.isGrouping(this.values)) { |