diff --git a/src/generics/lib.generics.ts b/src/generics/lib.generics.ts index dc097f4..0160db3 100644 --- a/src/generics/lib.generics.ts +++ b/src/generics/lib.generics.ts @@ -577,9 +577,10 @@ namespace __Array { function flatMap(this: T[], func: (v: T, i: number) => V[]): V[] { const result: V[] = []; for (let i = 0; i < this.length; i++) { - // moved out of the array func made, which goes when this loop turns + // read, as flat reads: func may give an array it holds on to (the same one for every + // element, a row of a table), so nothing is moved out of it const mapped = func(this[i], i); - __moveAll(mapped, result); + for (const v of mapped) result.push(v); } return result; diff --git a/tests/array_flatMap_shared.ts b/tests/array_flatMap_shared.ts new file mode 100644 index 0000000..f78c025 --- /dev/null +++ b/tests/array_flatMap_shared.ts @@ -0,0 +1,25 @@ +// not own: a callback there cannot return an array it does not own ("borrows a captured variable") +// flatMap reads the array its callback gives: one the callback did not make is left as it was. +function main() { + const ones: number[] = [1, 2, 3]; + + // the same array for every element + const pair: number[] = [7, 8]; + const repeated = ones.flatMap((v: number, i: number) => pair); + assert(repeated.join(",") == "7,8,7,8,7,8", "flatMap of one array given three times"); + assert(pair.length == 2 && pair.join(",") == "7,8", "flatMap leaves the array it was given"); + + // rows of a table + const rows: string[][] = [["a", "b"], ["c"]]; + const cells = [1, 0, 1].flatMap((v: number, i: number) => rows[v]); + assert(cells.join(",") == "c,a,b,c", "flatMap of arrays held elsewhere"); + assert(rows[0].length == 2 && rows[1].length == 1, "which stay as they were"); + + // the Array class + const a = new Array(); + a.push(1, 2); + assert(a.flatMap((v: number, i: number) => pair).join(",") == "7,8,7,8", "Array.flatMap"); + assert(pair.length == 2, "Array.flatMap leaves it too"); + + console.log("ALL DONE"); +}