diff --git a/Base/res/js/Spreadsheet/runtime.js b/Base/res/js/Spreadsheet/runtime.js index d34b3e3ffe0..a0604d24f39 100644 --- a/Base/res/js/Spreadsheet/runtime.js +++ b/Base/res/js/Spreadsheet/runtime.js @@ -189,6 +189,40 @@ class CommonRange { this.forEach(val => cells.push(val)); return cells; } + + filter(matches) { + const cells = []; + this.forEach(cell => { + if (matches(cell)) cells.push(cell); + }); + return new SplitRange(cells); + } +} + +class SplitRange extends CommonRange { + constructor(cells) { + super(); + this.cells = cells; + } + + static fromNames(...cellNames) { + return new SplitRange(cellNames.map(Position.from_name)); + } + + first() { + return this.cellNames[0]; + } + + forEach(callback) { + for (const cell of this.cells) { + if (callback(cell) === Break) return; + } + } + + toString() { + const namesFormatted = this.cells.map(cell => '"' + cell.name + '"').join(", "); + return `SplitRange.fromNames(${namesFormatted})`; + } } class Ranges extends CommonRange { @@ -388,7 +422,7 @@ function numericResolve(cells) { } function resolve(cells) { - const isRange = cells instanceof Range || cells instanceof Ranges; + const isRange = cells instanceof CommonRange; return isRange ? cells.toArray().map(cell => cell.value()) : cells; } diff --git a/Userland/Applications/Spreadsheet/Tests/basic.js b/Userland/Applications/Spreadsheet/Tests/basic.js index f8b6074ae96..26573aa1b90 100644 --- a/Userland/Applications/Spreadsheet/Tests/basic.js +++ b/Userland/Applications/Spreadsheet/Tests/basic.js @@ -189,6 +189,17 @@ describe("Range", () => { }); }); +describe("SplitRange", () => { + makeSheet(); + test("Range#filter => SplitRange", () => { + const range = R`A0:B`.filter(c => c.value() % 2 === 1); + expect(range.toString()).toEqual('SplitRange.fromNames("A0", "A2", "B0", "B2")'); + expect(resolve(range)).toEqual(["1", "3", "1", "9"]); + expect(numericResolve(range)).toEqual([1, 3, 1, 9]); + expect(count(range)).toEqual(4); + }); +}); + describe("R function", () => { makeSheet();