UNPKG

predictionary

Version:

JavaScript dictionary-based word prediction library.

163 lines (147 loc) 5.66 kB
import itemFactory from "./itemFactory.mjs"; function Dictionary() { let thiz = this; let _dict = {}; let _lastPredictionInput = null; let _lastPredictions = null; thiz.load = function (dictionaryJSON) { let importDict = JSON.parse(dictionaryJSON); Object.keys(importDict).forEach(key => { importDict[key].w = key; }); _dict = importDict; }; thiz.toJSON = function () { let copy = JSON.parse(JSON.stringify(_dict)); Object.keys(copy).forEach(key => { delete copy[key].w; }); return JSON.stringify(copy); }; thiz.addWord = function (word, rank) { if (!word) { return; } if (!_dict[word]) { _dict[word] = itemFactory.createItem(word, rank); } }; thiz.addWords = function (words) { if (!(words instanceof Array) || words.length === 0) { throw 'words to add must be an array with at least one element.'; } words.forEach(word => { thiz.addWord(word); }); }; thiz.deleteWord = function (word, ignoreCase) { Object.keys(_dict).forEach(dictWord => { let equalWord = ignoreCase ? word.toUpperCase() === dictWord.toUpperCase() : word === dictWord; if (equalWord) { delete _dict[dictWord]; } else { let dictElement = _dict[dictWord]; Object.keys(dictElement.t).forEach(transistionWord => { let equalTransitionWord = ignoreCase ? word.toUpperCase() === transistionWord.toUpperCase() : word === transistionWord; if (equalTransitionWord) { delete dictElement.t[transistionWord]; } }) } }); }; thiz.contains = function (word, matchCase) { if (matchCase) { return !!_dict[word]; } else { return !!getBestFittingItem(word); } }; thiz.predictCompleteWord = function (input, options) { input = input || ''; options = options || {}; //maxPredictions, predictionMinDepth, predictionMaxDepth, compareFn let possiblePredictions = []; Object.keys(_dict).forEach(key => { if (key.toLowerCase().indexOf(input.toLowerCase()) === 0) { possiblePredictions.push(_dict[key]); } }); if (possiblePredictions.length === 0 && input.length > 1) { let result = null; if (_lastPredictionInput && _lastPredictions && input.indexOf(_lastPredictionInput) === 0) { result = _lastPredictions; } else { result = thiz.predictCompleteWord(input.substring(0, input.length - 1), options); } result.forEach(element => { element.fuzzyMatch = true; }); return result; } _lastPredictionInput = input; _lastPredictions = possiblePredictions.map(element => { return { word: element.w, frequency: element.f, rank: element.r }; }); return _lastPredictions; }; thiz.predictNextWord = function (previousWord, options) { let items = getDictItemsAnyCase(previousWord); let predictions = []; items.forEach(item => { Object.keys(item.t).forEach(key => { predictions.push({ word: key, frequency: item.t[key] }); }); }); return predictions; }; thiz.learn = function (chosenWord, previousWord, addIfNotExisting) { if (!chosenWord || (!thiz.contains(chosenWord) && !addIfNotExisting)) { return; } if (addIfNotExisting && chosenWord && !thiz.contains(chosenWord)) { thiz.addWord(chosenWord); } if (addIfNotExisting && previousWord && !thiz.contains(previousWord)) { thiz.addWord(previousWord); } let previousWordItem = getBestFittingItem(previousWord); let chosenWordItem = getBestFittingItem(chosenWord); chosenWordItem.f++; if (previousWordItem && previousWordItem.t) { if (previousWordItem.t[chosenWordItem.w]) { previousWordItem.t[chosenWordItem.w]++; } else { previousWordItem.t[chosenWordItem.w] = 1; } } }; thiz.getWords = function () { return Object.keys(_dict); }; function getDictItemsAnyCase(word) { if (!word) { return []; } let items = []; if (_dict[word]) items.push(_dict[word]); if (_dict[word.toLowerCase()] && items.indexOf(_dict[word.toLowerCase()]) === -1) items.push(_dict[word.toLowerCase()]); if (_dict[word.toUpperCase()] && items.indexOf(_dict[word.toUpperCase()]) === -1) items.push(_dict[word.toUpperCase()]); if (_dict[capitalize(word)] && items.indexOf(_dict[capitalize(word)]) === -1) items.push(_dict[capitalize(word)]); return items; } function getBestFittingItem(word) { let items = getDictItemsAnyCase(word); return items.length > 0 ? items[0] : null; } function capitalize(string) { return string.charAt(0).toUpperCase() + string.slice(1); } } export default Dictionary;