Last active
May 31, 2021 19:12
-
-
Save nurdabolatov/68e689a716c0b4d54454432726d5eefd to your computer and use it in GitHub Desktop.
Trie Search in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Source: https://nurdabolatov.com/trie-search-in-javascript --> | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Trie Search in JavaScript</title> | |
</head> | |
<body> | |
<input id="search" placeholder="Search" onkeyup="search()"/> | |
<ul id="results"> | |
</ul> | |
<script> | |
const textSnippets = [ | |
'hello people', | |
'Welcome to my World!', | |
'Test your search results', | |
'This is another test', | |
]; | |
const renderSearchResults = (results) => { | |
const ul = document.getElementById('results'); | |
ul.innerHTML = ''; | |
for (const result of results) { | |
const li = document.createElement('li'); | |
const text = document.createTextNode(textSnippets[result]); | |
li.appendChild(text); | |
ul.appendChild(li); | |
} | |
}; | |
const naiveSearch = () => { | |
const input = document.getElementById('search'); | |
const value = input.value.toLowerCase(); | |
const results = new Set(); | |
for (let i = 0; i < textSnippets.length; i++) { | |
const words = textSnippets[i].split(' '); | |
for (const word of words) { | |
if (word.toLowerCase().startsWith(value)) { | |
results.add(i); | |
break; | |
} | |
} | |
} | |
renderSearchResults(results); | |
}; | |
// This is to create an empty node in our graph | |
const createNode = () => { | |
const node = new Map(); | |
node.set('results', new Set()); | |
return node; | |
}; | |
const root = createNode(); | |
const buildTrie = () => { | |
// This function adds the word to the Trie and | |
// the index to results field while traversing the tree. | |
// Here the index is the index of text snippet that | |
// contains the word. | |
const processWord = (index, word) => { | |
let current = root; | |
for (const letter of word.toLowerCase()) { | |
// Create a new node if the path doesn't exist | |
if (!current.has(letter)) { | |
current.set(letter, createNode()); | |
} | |
// Follow the path | |
current = current.get(letter); | |
// Add the index to results field | |
// in every node on the path | |
current.get('results').add(index); | |
} | |
} | |
// We break down every text snippet into words | |
// and add every word into the Trie | |
const processTextSnippet = (index, textSnippet) => { | |
words = textSnippet.split(' '); | |
for (const word of words) { | |
processWord(index, word); | |
} | |
} | |
for (let i = 0; i < textSnippets.length; i++) { | |
processTextSnippet(i, textSnippets[i]); | |
} | |
}; | |
// We need to run this once when the application is loaded | |
buildTrie(); | |
const search = () => { | |
const input = document.getElementById('search'); | |
let current = root; | |
for (const letter of input.value.toLowerCase()) { | |
// If the path doesn't exist, we return an empty result | |
if (!current.has(letter)) { | |
renderSearchResults(new Set()); | |
return; | |
} | |
current = current.get(letter); | |
} | |
renderSearchResults(current.get('results')); | |
}; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment