UNPKG

fuzzy-rater

Version:

Tooling for fuzzily rating text according to some query

98 lines 7.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FuzzyWordMatcher = void 0; const createFuzzyNFATemplate_1 = require("./createFuzzyNFATemplate"); const NFADFA_1 = require("../../DFA/NFADFA/NFADFA"); const merge_1 = require("../../utils/merge"); /** * A fuzzy word matcher that can be used to find a word in a number of items. * Initial setup time is relatively long, but matching per string happens in linear time. */ class FuzzyWordMatcher { /** * Constructs a new fuzzy word matcher * @param word The word to look for * @param maxDistance The maximum error */ constructor(word, maxDistance) { this.word = word; this.maxDistance = maxDistance; this.initialize(word, maxDistance); } /** * Initializes the data structures used for rating * @param word The word to look for * @param maxDistance The maximal allowed distance */ initialize(word, maxDistance) { const nfaTemplate = createFuzzyNFATemplate_1.createFuzzyNFATemplate(word, maxDistance); this.NFA = new NFADFA_1.NFADFA(nfaTemplate); } /** * Finds the best match in a set of NFA nodes * @param matches The nodes to find the best match in * @param getNode Retrieves the node data * @returns The best match */ getBestMatch(matches, getNode) { const best = matches.reduce((best, m) => { const node = getNode(m); return node.matched && (best == null || node.distance < best.distance) ? { item: m, distance: node.distance } : best; }, undefined); return best === null || best === void 0 ? void 0 : best.item; } /** * Retrieves the best match in the given text * @param text The text to find the query word in * @returns Whether the text matched, and the distance from the query word */ getMatch(text) { // Execute the DFA const matches = this.NFA.execute(text); // Find the best match const best = this.getBestMatch(matches, node => node); // Return the result if (best) return { matched: true, distance: best.distance }; return { matched: false, distance: Infinity }; } /** * Retrieves the best match in the given text, and data of how to obtain it * @param text The text to find the query word in * @returns Whether the text matched, and the distance from the query word, and how the text differed */ getMatchData(text) { var _a; const matches = this.NFA.executeTraced(text); const best = this.getBestMatch(matches, ({ final }) => final); const trace = best === null || best === void 0 ? void 0 : best.getPath(); // Convert the NFA trace to an alterations array if (best && trace) { const alterations = (_a = trace.reduce(({ alterations, index }, { transition }) => { var _a; const target = { index, character: transition.type == "skip" ? "" : text[index], }; const query = { index: transition.index, character: (_a = transition.character) !== null && _a !== void 0 ? _a : "", }; return { alterations: merge_1.add(alterations, { target, query, type: transition.type, }), index: transition.type == "skip" ? index : index + 1, }; }, { alterations: [], index: 0 })) === null || _a === void 0 ? void 0 : _a.alterations; return { matched: true, distance: best.final.distance, alterations }; } return { matched: false, distance: Infinity, alterations: [] }; } } exports.FuzzyWordMatcher = FuzzyWordMatcher; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRnV6enlXb3JkTWF0Y2hlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9mdXp6eVJhdGUvd29yZE1hdGNoZXIvRnV6enlXb3JkTWF0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFBZ0U7QUFJaEUsb0RBQStDO0FBQy9DLDZDQUFzQztBQUV0Qzs7O0dBR0c7QUFDSCxNQUFhLGdCQUFnQjtJQUt6Qjs7OztPQUlHO0lBQ0gsWUFBbUIsSUFBWSxFQUFFLFdBQW1CO1FBQ2hELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBQy9CLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7OztPQUlHO0lBQ08sVUFBVSxDQUFDLElBQVksRUFBRSxXQUFtQjtRQUNsRCxNQUFNLFdBQVcsR0FBRywrQ0FBc0IsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLGVBQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTyxZQUFZLENBQ2xCLE9BQVksRUFDWixPQUFvQztRQUVwQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3BDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QixPQUFPLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDbEUsQ0FBQyxDQUFDLEVBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBQztnQkFD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