Skip to content

Instantly share code, notes, and snippets.

@nurdabolatov
Last active May 31, 2021 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nurdabolatov/68e689a716c0b4d54454432726d5eefd to your computer and use it in GitHub Desktop.
Save nurdabolatov/68e689a716c0b4d54454432726d5eefd to your computer and use it in GitHub Desktop.
Trie Search in JavaScript
<!-- 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