UNPKG

hyperformula

Version:

HyperFormula is a JavaScript engine for efficient processing of spreadsheet-like data and formulas

81 lines (79 loc) 3.51 kB
"use strict"; exports.__esModule = true; exports.AdvancedFind = void 0; var _InterpreterValue = require("../interpreter/InterpreterValue"); var _ArithmeticHelper = require("../interpreter/ArithmeticHelper"); var _binarySearch = require("../interpreter/binarySearch"); /** * @license * Copyright (c) 2025 Handsoncode. All rights reserved. */ const NOT_FOUND = -1; class AdvancedFind { constructor(dependencyGraph) { this.dependencyGraph = dependencyGraph; } advancedFind(keyMatcher, rangeValue, { returnOccurrence } = { returnOccurrence: 'first' }) { const range = rangeValue.range; const values = range === undefined ? rangeValue.valuesFromTopLeftCorner() : this.dependencyGraph.computeListOfValuesInRange(range); const initialIterationIndex = returnOccurrence === 'first' ? 0 : values.length - 1; const iterationCondition = returnOccurrence === 'first' ? i => i < values.length : i => i >= 0; const incrementIndex = returnOccurrence === 'first' ? i => i + 1 : i => i - 1; for (let i = initialIterationIndex; iterationCondition(i); i = incrementIndex(i)) { if (keyMatcher((0, _InterpreterValue.getRawValue)(values[i]))) { return i; } } return NOT_FOUND; } basicFind(searchKey, rangeValue, searchCoordinate, { ordering, ifNoMatch, returnOccurrence }) { const normalizedSearchKey = typeof searchKey === 'string' ? (0, _ArithmeticHelper.forceNormalizeString)(searchKey) : searchKey; const range = rangeValue.range; if (range === undefined) { return this.findNormalizedValue(normalizedSearchKey, rangeValue.valuesFromTopLeftCorner(), ifNoMatch, returnOccurrence); } if (ordering === 'none') { return this.findNormalizedValue(normalizedSearchKey, this.dependencyGraph.computeListOfValuesInRange(range), ifNoMatch, returnOccurrence); } return (0, _binarySearch.findLastOccurrenceInOrderedRange)(normalizedSearchKey, range, { searchCoordinate, orderingDirection: ordering, ifNoMatch }, this.dependencyGraph); } findNormalizedValue(searchKey, searchArray, ifNoMatch = 'returnNotFound', returnOccurrence = 'first') { const normalizedArray = searchArray.map(_InterpreterValue.getRawValue).map(val => typeof val === 'string' ? (0, _ArithmeticHelper.forceNormalizeString)(val) : val); if (ifNoMatch === 'returnNotFound') { return returnOccurrence === 'first' ? normalizedArray.indexOf(searchKey) : normalizedArray.lastIndexOf(searchKey); } const compareFn = ifNoMatch === 'returnLowerBound' ? (left, right) => (0, _binarySearch.compare)(left, right) : (left, right) => -(0, _binarySearch.compare)(left, right); let bestValue = ifNoMatch === 'returnLowerBound' ? -Infinity : Infinity; let bestIndex = NOT_FOUND; const initialIterationIndex = returnOccurrence === 'first' ? 0 : normalizedArray.length - 1; const iterationCondition = returnOccurrence === 'first' ? i => i < normalizedArray.length : i => i >= 0; const incrementIndex = returnOccurrence === 'first' ? i => i + 1 : i => i - 1; for (let i = initialIterationIndex; iterationCondition(i); i = incrementIndex(i)) { const value = normalizedArray[i]; if (value === searchKey) { return i; } if (compareFn(value, searchKey) > 0) { continue; } if (compareFn(bestValue, value) < 0) { bestValue = value; bestIndex = i; } } return bestIndex; } } exports.AdvancedFind = AdvancedFind;