Я понятия не имею, будет ли это намного быстрее, чуть быстрее, примерно таким же, чуть медленнее или намного медленнее, чем ваш первоначальный подход. Но есть основания полагать, что это может ускорить процесс. По сути, это реализация barebones tr ie.
const simpleTrie = (words) => {
const root = {}
const addCharToNode = (node, char) => node [char] || (node[char] = {})
const addChars = (node, [c = undefined, ...cs]) =>
c == undefined ? node : addChars (addCharToNode (node, c), cs)
const addSuffixes = (node, chars, [c = undefined, ...cs] = chars) =>
c == undefined ? node : addChars(node, chars) && addSuffixes (node, cs)
const findChars = (node, [c = undefined, ...cs]) =>
c == undefined ? true : c in node ? findChars (node [c], cs) : false
words .forEach (word => addSuffixes (root, word .split ('')))
return (word) => findChars (root, word .split (''))
}
const findWord = simpleTrie (["example", "defvalue", "harder", "klein", "rapper", "doesnt"]);
const result = ["exa", "val", "har", "esd", "elf"] .filter (word => ! findWord (word))
console .log (result)
Это неправильный tr ie, так как он находит любые подстроки добавленных слов. Это как предназначено для проблемы, хотя. Это также не позволяет добавлять или удалять слова из дерева; сложение было бы довольно просто. Удаление может быть сложнее. Но опять же, это не нужно для этой проблемы.
Если это действительно кажется улучшением, вы, вероятно, сможете выжать из нее гораздо большую производительность, заменив элегантные рекурсии императивными циклами.