From 52b947c96c4bbf3b8a0777cec6099d7b7de67856 Mon Sep 17 00:00:00 2001 From: ASDAlexander77 Date: Sat, 14 Nov 2026 14:50:09 +0000 Subject: [PATCH] flatMap reads the array its callback gives and leaves it as it was flatMap moved the elements out of the array the callback returned, which emptied one the callback did not make: the same array for every element, or a row of a table. [1, 2, 3].flatMap(v => pair) gave pair's elements once and left pair empty. It copies them now, as flat does. array_flatMap_shared.ts covers it on T[] and on Array. It is marked "// not own": -mm=own refuses a callback that returns an array it does not own, so the case does not arise there. Tested in release on Windows x64 for gc, rc, none and own; debug, Linux, x86 and wasm were not built locally. Co-Authored-By: Claude Fable 5.2 --- src/generics/lib.generics.ts | 5 +++-- tests/array_flatMap_shared.ts | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 tests/array_flatMap_shared.ts 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"); +}