d11 theme
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

124 lines
5.2 KiB

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Trie = exports.defaultTrieOptions = void 0;
const gensequence_1 = require("gensequence");
const suggest_1 = require("./suggest");
const util_1 = require("./util");
const walker_1 = require("./walker");
const _defaultTrieOptions = {
compoundCharacter: '+',
stripCaseAndAccentsPrefix: '~',
forbiddenWordPrefix: '!',
};
exports.defaultTrieOptions = Object.freeze(_defaultTrieOptions);
function mergeOptionalWithDefaults(options) {
const { compoundCharacter = exports.defaultTrieOptions.compoundCharacter, stripCaseAndAccentsPrefix = exports.defaultTrieOptions.stripCaseAndAccentsPrefix, forbiddenWordPrefix = exports.defaultTrieOptions.forbiddenWordPrefix, } = options || {};
return { compoundCharacter, stripCaseAndAccentsPrefix, forbiddenWordPrefix };
}
class Trie {
constructor(root, count, options) {
this.root = root;
this.count = count;
this._options = mergeOptionalWithDefaults(options);
}
/**
* Number of words in the Trie
*/
size() {
var _a;
this.count = (_a = this.count) !== null && _a !== void 0 ? _a : util_1.countWords(this.root);
return this.count;
}
get options() {
return this._options;
}
find(text, minCompoundLength = false) {
const minLength = !minCompoundLength || minCompoundLength === true ? undefined : minCompoundLength;
return minCompoundLength ? this.findCompound(text, minLength) : this.findExact(text);
}
findCompound(text, minCompoundLength = 3, minLength = 0) {
let n = this.root;
let p;
let q;
for (p = 0; n && n.c && p < text.length; p = q) {
n = n.c.get(text[p]);
q = p + 1;
if (n && n.f && q < text.length && q >= minCompoundLength) {
const r = this.findCompound(text.slice(q), minCompoundLength, minCompoundLength);
if (r && r.f) {
return r;
}
}
}
return p === text.length && p >= minLength ? n : undefined;
}
findExact(text) {
let n = this.root;
let p;
for (p = 0; n && n.c && p < text.length; ++p) {
n = n.c.get(text[p]);
}
return p === text.length ? n : undefined;
}
has(word, minCompoundLength) {
const n = this.find(word, minCompoundLength);
return !!n && util_1.isWordTerminationNode(n);
}
/**
* Provides an ordered sequence of words with the prefix of text.
*/
completeWord(text) {
const n = this.find(text);
return gensequence_1.genSequence(n && util_1.isWordTerminationNode(n) ? [text] : []).concat(n ? util_1.iteratorTrieWords(n).map((suffix) => text + suffix) : []);
}
/**
* Suggest spellings for `text`. The results are sorted by edit distance with changes near the beginning of a word having a greater impact.
* @param text - the text to search for
* @param maxNumSuggestions - the maximum number of suggestions to return.
* @param compoundMethod - Use to control splitting words.
* @param numChanges - the maximum number of changes allowed to text. This is an approximate value, since some changes cost less than others.
* the lower the value, the faster results are returned. Values less than 4 are best.
*/
suggest(text, maxNumSuggestions, compoundMethod, numChanges) {
return this.suggestWithCost(text, maxNumSuggestions, compoundMethod, numChanges).map((a) => a.word);
}
/**
* Suggest spellings for `text`. The results are sorted by edit distance with changes near the beginning of a word having a greater impact.
* The results include the word and adjusted edit cost. This is useful for merging results from multiple tries.
*/
suggestWithCost(text, maxNumSuggestions, compoundMethod, numChanges) {
return suggest_1.suggest(this.root, text, maxNumSuggestions, compoundMethod, numChanges);
}
/**
* genSuggestions will generate suggestions and send them to `collector`. `collector` is responsible for returning the max acceptable cost.
* Costs are measured in weighted changes. A cost of 100 is the same as 1 edit. Some edits are considered cheaper.
* Returning a MaxCost < 0 will effectively cause the search for suggestions to stop.
*/
genSuggestions(collector, compoundMethod) {
collector.collect(suggest_1.genSuggestions(this.root, collector.word, compoundMethod));
}
/**
* Returns an iterator that can be used to get all words in the trie. For some dictionaries, this can result in millions of words.
*/
words() {
return util_1.iteratorTrieWords(this.root);
}
/**
* Allows iteration over the entire tree.
* On the returned Iterator, calling .next(goDeeper: boolean), allows for controlling the depth.
*/
iterate() {
return walker_1.walker(this.root);
}
insert(word) {
util_1.insert(word, this.root);
return this;
}
static create(words, options) {
const root = util_1.createTriFromList(words);
util_1.orderTrie(root);
return new Trie(root, undefined, options);
}
}
exports.Trie = Trie;
//# sourceMappingURL=trie.js.map