1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 11:17:43 +00:00

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

This commit is contained in:
u9g 2022-02-27 16:05:27 -05:00 committed by Ali Mohammad Pur
parent d047f26a74
commit 4eb2c70a03
3 changed files with 31 additions and 32 deletions

View file

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

View file

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

View file

@ -46,24 +46,32 @@ describe("Basic functions", () => {
expect(reduce).toBeDefined(); expect(reduce).toBeDefined();
expect(reduce(acc => acc + 1, 0, [1, 2, 3, 4])).toEqual(4); expect(reduce(acc => acc + 1, 0, [1, 2, 3, 4])).toEqual(4);
expect(reduce(acc => acc + 1, 0, [])).toEqual(0); 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", () => { test("numericReduce", () => {
expect(numericReduce).toBeDefined(); expect(numericReduce).toBeDefined();
expect(numericReduce(acc => acc + 1, 0, [1, 2, 3, 4])).toEqual(4); expect(numericReduce(acc => acc + 1, 0, [1, 2, 3, 4])).toEqual(4);
expect(numericReduce(acc => acc + 1, 0, [])).toEqual(0); 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", () => { test("numericResolve", () => {
expect(numericResolve).toBeDefined(); 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([])).toEqual([]);
expect(numericResolve(R`A0:A2`)).toEqual([0, 1, 2]);
expect(numericResolve(R`A0:A0`)).toEqual([0]);
}); });
test("resolve", () => { test("resolve", () => {
expect(resolve).toBeDefined(); 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([])).toEqual([]);
expect(resolve(R`A0:A2`)).toEqual(["0", "1", "2"]);
expect(resolve(R`A0:A0`)).toEqual(["0"]);
}); });
}); });