diff --git a/Base/res/js/Spreadsheet/runtime.js b/Base/res/js/Spreadsheet/runtime.js index a0604d24f3..38977a4aee 100644 --- a/Base/res/js/Spreadsheet/runtime.js +++ b/Base/res/js/Spreadsheet/runtime.js @@ -197,6 +197,19 @@ class CommonRange { }); return new SplitRange(cells); } + + unique() { + const cells = []; + const values = new Set(); + this.forEach(cell => { + const value = cell.value(); + if (!values.has(value)) { + values.add(value); + cells.push(cell); + } + }); + return new SplitRange(cells); + } } class SplitRange extends CommonRange { diff --git a/Userland/Applications/Spreadsheet/Tests/basic.js b/Userland/Applications/Spreadsheet/Tests/basic.js index 26573aa1b9..9f04e251b8 100644 --- a/Userland/Applications/Spreadsheet/Tests/basic.js +++ b/Userland/Applications/Spreadsheet/Tests/basic.js @@ -198,6 +198,21 @@ describe("SplitRange", () => { expect(numericResolve(range)).toEqual([1, 3, 1, 9]); expect(count(range)).toEqual(4); }); + + test("Range#unique => SplitRange", () => { + makeSheet(); + + const origRange = R`A0:B`; + const uniqueRange = origRange.unique(); + expect(uniqueRange.toString()).toEqual( + 'SplitRange.fromNames("A0", "A1", "A2", "B1", "B2")' + ); + + const uniqueCount = count(uniqueRange); + // We expect that making a set (unique array) of the original range should equal the length of our unique range + expect(new Set(resolve(origRange)).size).toEqual(uniqueCount); + expect(uniqueCount).toEqual(5); + }); }); describe("R function", () => {