Skip to content

Instantly share code, notes, and snippets.

@rajivpo
Created August 6, 2020 04:48
Show Gist options
  • Save rajivpo/8d4afa76cdf6a9f68cd01b59b6ca76d7 to your computer and use it in GitHub Desktop.
Save rajivpo/8d4afa76cdf6a9f68cd01b59b6ca76d7 to your computer and use it in GitHub Desktop.
var fs = require('fs'); // import for index_emails
function Trie() {
this.head = {};
};
// want to make sure we have valid words
Trie.prototype.validate = function(word) {
if ((word === undefined) || (word === null) || (typeof word !== "string")) throw "invalid input";
}
// basic gist is to check if a node exists in a given sequence (prefix) and if it doesn't create a new one
Trie.prototype.add = function(word, value=null) {
this.validate(word)
var node = this.head;
for (var i = 0; i < word.length; i++) {
if(!(word[i] in node)) {
node[word[i]] = {};
}
node = node[word[i]]
};
node.word = word
// this was added for the sake of having multiple non-word values for a single path in the trie
if (value) {
node.value = Array.isArray(node.value) ? [...node.value, value] : [value]
}
};
// follow the trie from node to node to see if it has it
Trie.prototype.contains = function(word) {
this.validate(word)
var node = this.head;
for (var i = 0; i < word.length; i++) {
if(!(word[i] in node)) {
return false;
}
node = node[word[i]]
};
return node.word === word;
};
Trie.prototype.get = function(word) {
this.validate(word)
var node = this.head;
for (var i = 0; i < word.length; i++) {
if(!(word[i] in node)) {
return false;
}
node = node[word[i]]
};
return node.value;
};
// follow the trie from node to node to see if it has it
Trie.prototype.contains = function(word) {
this.validate(word)
var node = this.head;
for (var i = 0; i < word.length; i++) {
if(!(word[i] in node)) {
return false;
}
node = node[word[i]]
};
return node.word === word;
};
// doing this async would be preferable as it's currently blocking and would prevent it from doing anything else
Trie.prototype.index_emails = function(path) {
var self = this
fs.readdirSync(path).forEach(function(dirname) {
var currentPath = path + '/' + dirname
var isDir = fs.lstatSync(currentPath).isDirectory()
// if a current dir level has both files and dirs we need to recurse accordingly
if (isDir) {
self.index_emails(currentPath)
} else {
var text = fs.readFileSync(currentPath, "utf-8");
words = text.toLowerCase().split(' ')
words.forEach(function(word) {
self.add(word, currentPath)
})
}
})
return self;
}
Trie.prototype.test = function(word, trie) {
return trie.get(word)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment