| 1 | /** |
| 2 | * Helper to iterate over multiple arrays at the same time, or to iterate over |
| 3 | * an array with an index, or both. |
| 4 | */ |
| 5 | export function* enumerate<T extends [unknown, ...unknown[]]>( |
| 6 | ...arrays: { [K in keyof T]: ArrayLike<T[K]> } |
| 7 | ): Generator<[...items: T, index: number]> { |
| 8 | const { length } = arrays[0]; |
| 9 | arrays.forEach((x) => ASSERT(x.length === length), "All arrays must be equal in length"); |
| 10 | for (let i = 0; i < length; i += 1) yield arrays.map((x) => x[i]!).concat(i) as [...T, number]; |
| 11 | } |
| 12 | |
| 13 | export function mapMany<T extends [unknown, ...unknown[]], O>( |
| 14 | arrays: { [K in keyof T]: ArrayLike<T[K]> }, |
| 15 | map: (...args: [...items: T, index: number]) => O, |
| 16 | ): O[] { |
| 17 | const { length } = arrays[0]; |
| 18 | arrays.forEach((x) => ASSERT(x.length === length), "All arrays must be equal in length"); |
| 19 | return Array.from({ length }, (_, i) => map(...(arrays.map((a) => a[i]!).concat(i) as [...T, number]))); |
| 20 | } |
| 21 | |
| 22 | import { ASSERT } from "./assert.ts"; |