Browse Source

Spreadsheet: Make Range(s).forEach() return Position objects

u9g 3 năm trước cách đây
mục cha
commit
4eb2c70a03

+ 19 - 28
Base/res/js/Spreadsheet/runtime.js

@@ -220,7 +220,7 @@ class Range {
 
         outer: for (const range of ranges) {
             for (let row = range.rowStart; row <= range.rowEnd; row += this.rowStep) {
-                if (callback(range.column + row) === Break) break outer;
+                if (callback(new Position(range.column, row)) === Break) break outer;
             }
         }
     }
@@ -328,26 +328,23 @@ function sheet(name) {
 }
 
 function reduce(op, accumulator, cells) {
-    cells.forEach(name => {
-        let cell = thisSheet[name];
-        accumulator = op(accumulator, cell);
-    });
-    return accumulator;
+    return resolve(cells).reduce(op, accumulator);
 }
 
 function numericReduce(op, accumulator, cells) {
-    return reduce((acc, x) => op(acc, Number(x)), accumulator, cells);
+    return numericResolve(cells).reduce(op, accumulator);
 }
 
 function numericResolve(cells) {
-    const values = [];
-    cells.forEach(name => values.push(Number(thisSheet[name])));
-    return values;
+    return resolve(cells).map(str => (str === "" || str == null ? NaN : integer(str)));
 }
 
 function resolve(cells) {
-    const values = [];
-    cells.forEach(name => values.push(thisSheet[name]));
+    let values = [];
+    if (cells instanceof Range || cells instanceof Ranges)
+        cells.forEach(cell => values.push(cell.value()));
+    else values = cells;
+
     return values;
 }
 
@@ -517,39 +514,33 @@ function internal_lookup(
     }
 
     let i = 0;
-    let didMatch = false;
     let value = null;
-    let matchingName = null;
-    lookup_inputs.forEach(name => {
-        value = thisSheet[name];
+    let found_input = null;
+    lookup_inputs.forEach(cell => {
+        value = cell.value();
         if (matches(value)) {
-            didMatch = true;
-            matchingName = name;
+            found_input = cell;
             return Break;
         }
         ++i;
     });
 
-    if (!didMatch) return if_missing;
+    if (found_input == null) return if_missing;
 
     if (lookup_outputs === undefined) {
-        if (reference) return Position.from_name(matchingName);
+        if (reference) return found_input;
 
         return value;
     }
 
-    lookup_outputs.forEach(name => {
-        matchingName = name;
-        if (i === 0) return Break;
-        --i;
-    });
+    const found_output = lookup_outputs.at(i);
 
-    if (i > 0)
+    if (found_output == null)
         throw new Error("Lookup target length must not be smaller than lookup source length");
 
-    if (reference) return Position.from_name(matchingName);
+    if (reference) return found_output;
 
-    return thisSheet[matchingName];
+    return found_output.value();
 }
 
 function lookup(req_lookup_value, lookup_inputs, lookup_outputs, if_missing, mode) {

+ 2 - 2
Userland/Applications/Spreadsheet/Tests/basic.js

@@ -118,7 +118,7 @@ describe("Range", () => {
             for (const row of [0, 1, 2]) sheet.setCell(col, row, Math.pow(i++, 2));
 
         sheet.focusCell("A", 0);
-        expect(R`A0:A2`.at(2)).toEqual("A2");
-        expect(Ranges.from(R`A0:A2`, R`B0:B2`).at(5)).toEqual("B2");
+        expect(R`A0:A2`.at(2).name).toEqual("A2");
+        expect(Ranges.from(R`A0:A2`, R`B0:B2`).at(5).name).toEqual("B2");
     });
 });

+ 10 - 2
Userland/Applications/Spreadsheet/Tests/free-functions.js

@@ -46,24 +46,32 @@ describe("Basic functions", () => {
         expect(reduce).toBeDefined();
         expect(reduce(acc => acc + 1, 0, [1, 2, 3, 4])).toEqual(4);
         expect(reduce(acc => acc + 1, 0, [])).toEqual(0);
+        expect(reduce((acc, x) => acc + "|" + x.toString(), 0, R`A0:A2`)).toEqual("0|0|1|2");
+        expect(reduce((acc, x) => acc + "|" + x.toString(), 0, R`A0:A0`)).toEqual("0|0");
     });
 
     test("numericReduce", () => {
         expect(numericReduce).toBeDefined();
         expect(numericReduce(acc => acc + 1, 0, [1, 2, 3, 4])).toEqual(4);
         expect(numericReduce(acc => acc + 1, 0, [])).toEqual(0);
+        expect(numericReduce((acc, x) => acc + x, 19, R`A0:A2`)).toEqual(22);
+        expect(numericReduce(acc => acc + 1, 3, R`A0:A0`)).toEqual(4);
     });
 
     test("numericResolve", () => {
         expect(numericResolve).toBeDefined();
-        expect(numericResolve(["A0", "A1", "A2"])).toEqual([0, 1, 2]);
+        expect(numericResolve(["0", "1", "2"])).toEqual([0, 1, 2]);
         expect(numericResolve([])).toEqual([]);
+        expect(numericResolve(R`A0:A2`)).toEqual([0, 1, 2]);
+        expect(numericResolve(R`A0:A0`)).toEqual([0]);
     });
 
     test("resolve", () => {
         expect(resolve).toBeDefined();
-        expect(resolve(["A0", "A1", "A2"])).toEqual(["0", "1", "2"]);
+        expect(resolve(["A", "B", "C"])).toEqual(["A", "B", "C"]);
         expect(resolve([])).toEqual([]);
+        expect(resolve(R`A0:A2`)).toEqual(["0", "1", "2"]);
+        expect(resolve(R`A0:A0`)).toEqual(["0"]);
     });
 });