UNPKG

fuzzy-rater

Version:

Tooling for fuzzily rating text according to some query

164 lines 10.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getID = exports.getTransitions = exports.createFuzzyNFATemplate = void 0; /** * Creates a new dfa template based on the query and max distance * @param query The query to create a template for * @param maxDistance The maximal allowed distance * @param exitOnMatch Whether the NFA should exit out of the node after match * @returns A dfa template */ function createFuzzyNFATemplate(query, maxDistance, exitOnMatch = false) { const nodes = []; // Add the initial node nodes.push({ ID: getID(query, 0, -1), initial: true, transitions: [...getTransitions(query, maxDistance, 0, -1)], metadata: { matched: false, searchIndex: 0, distance: 0, }, }); // Compute the grid of nodes for (let dist = 0; dist <= maxDistance; dist++) { for (let i = 0; i < query.length; i++) { nodes.push({ ID: getID(query, dist, i), initial: false, transitions: [ ...getTransitions(query, maxDistance, dist, i, exitOnMatch), ], metadata: { matched: i + 1 == query.length, searchIndex: i + 1, distance: dist, }, }); } } return nodes; } exports.createFuzzyNFATemplate = createFuzzyNFATemplate; /** * Retrieves all the transitions for a given node * @param query The query the transitions are for * @param maxDist The maximal allowed distance * @param dist The current distance * @param index The index of character matched so far * @param exitOnMatch Whether the NFA should exit out of the node after match * @returns The set of transitions from this node */ function getTransitions(query, maxDist, dist, index, exitOnMatch = false) { const nextIndex = index + 1; const nextChar = query[nextIndex]; const transitions = []; if (nextChar) { // Literal character match transitions.push({ to: getID(query, dist, nextIndex), type: "character", character: nextChar, metadata: { type: "match", index: nextIndex, character: nextChar, }, }); if (dist < maxDist) { // Skip query character transitions.push({ to: getID(query, dist + 1, nextIndex), type: "empty", metadata: { type: "skip", index: nextIndex, character: nextChar, }, }); // Replace query character transitions.push({ to: getID(query, dist + 1, nextIndex), type: "remaining", metadata: { type: "replace", index: nextIndex, character: nextChar, }, }); } } if (dist < maxDist && -1 < index && index < query.length - 1) { // Insert random character in the query transitions.push({ to: getID(query, dist + 1, index), type: "remaining", metadata: { index: nextIndex, type: "insert", }, }); } if (index == -1) { // Match any number of characters before query (including the first character itself) transitions.push({ to: getID(query, dist, index), type: "remaining", metadata: { index: nextIndex, type: "ignore", }, }); transitions.push({ to: getID(query, dist, index), type: "character", character: nextChar, metadata: { index: nextIndex, type: "ignore", }, }); } if (nextIndex == query.length) { if (!exitOnMatch) { // Match any number of characters after query transitions.push({ to: getID(query, dist, index), type: "remaining", metadata: { index: nextIndex, type: "ignore", }, }); } else { // Match any number of characters after query transitions.push({ to: getID(query, 0, -1), type: "empty", metadata: { index: nextIndex, type: "restart", }, }); } } return transitions; } exports.getTransitions = getTransitions; /** * Retrieves the ID for a node with the given data * @param query The query the node is for * @param dist The correctness distance the node is for * @param index The character index matched by the node * @returns THe ID for the node */ function getID(query, dist, index) { return index == -1 ? `start:${dist}` : `${index}:${query.substring(0, index + 1)}-${dist}`; // return `${index}:${dist}`; } exports.getID = getID; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlRnV6enlORkFUZW1wbGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9mdXp6eVJhdGUvd29yZE1hdGNoZXIvY3JlYXRlRnV6enlORkFUZW1wbGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFNQTs7Ozs7O0dBTUc7QUFDSCxTQUFnQixzQkFBc0IsQ0FDbEMsS0FBYSxFQUNiLFdBQW1CLEVBQ25CLGNBQXVCLEtBQUs7SUFFNUIsTUFBTSxLQUFLLEdBQUcsRUFHWCxDQUFDO0lBRUosdUJBQXVCO0lBQ3ZCLEtBQUssQ0FBQyxJQUFJLENBQUM7UUFDUCxFQUFFLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdkIsT0FBTyxFQUFFLElBQUk7UUFDYixXQUFXLEVBQUUsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNELFFBQVEsRUFBRTtZQUNOLE9BQU8sRUFBRSxLQUFLO1lBQ2QsV0FBVyxFQUFFLENBQUM7WUFDZCxRQUFRLEVBQUUsQ0FBQztTQUNkO0tBQ0osQ0FBQyxDQUFDO0lBRUgsNEJBQTRCO0lBQzVCLEtBQUssSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLElBQUksSUFBSSxXQUFXLEVBQUUsSUFBSSxFQUFFLEVBQUU7UUFDNUMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbkMsS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDUCxFQUFFLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUN6QixPQUFPLEVBQUUsS0FBSztnQkFDZCxXQUFXLEVBQUU7b0JBQ1QsR0FBRyxjQUFjLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVB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