Created
July 27, 2018 06:33
-
-
Save ManasJayanth/612095d5bac98e7ec8c941c8bc7445a3 to your computer and use it in GitHub Desktop.
Debalina - zipcode search with tries
This file contains 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
const root = document.getElementById('root'); | |
class TrieNode{ | |
constructor(c) { | |
this.key = c; | |
this.parent = null; | |
this.children = {}; // Hash mapping character to next level | |
this.end = false; // End of node | |
this.data = null | |
} | |
getWord() { | |
var output = []; | |
var node = this; | |
// Traverse back to parent to generate the word | |
while (node !== null) { | |
output.unshift(node.key); | |
node = node.parent; | |
} | |
return output.join(''); | |
} | |
} | |
class Trie { | |
constructor() { | |
this.root = new TrieNode(null); | |
} | |
// Inserts a word | |
insert(word, data) { | |
var node = this.root; | |
// for every character in the word | |
for(var i = 0; i < word.length; i++) { | |
// check to see if character node exists in children. | |
if (!node.children[word[i]]) { | |
// if it doesn't exist, we then create it. | |
node.children[word[i]] = new TrieNode(word[i]); | |
// we also assign the parent to the child node. | |
node.children[word[i]].parent = node; | |
} | |
// proceed to the next depth in the trie. | |
node = node.children[word[i]]; | |
// finally, we check to see if it's the last word. | |
if (i == word.length-1) { | |
// if it is, we set the end flag to true. | |
node.data = node.data ? node.data.concat([data]): [ data ]; | |
node.end = true; | |
} | |
} | |
} | |
// Check if it contains the word. | |
contains(word) { | |
var node = this.root; | |
// for every character in the word | |
for(var i = 0; i < word.length; i++) { | |
// check to see if character node exists in children. | |
if (node.children[word[i]]) { | |
// if it exists, proceed to the next depth of the trie. | |
node = node.children[word[i]]; | |
} else { | |
// doesn't exist, return false since it's not a valid word. | |
return false; | |
} | |
} | |
// we finished going through all the words, but is it a whole word? | |
return node.end; | |
} | |
// returns all words with given prefix | |
find(prefix) { | |
var node = this.root; | |
var output = []; | |
// for every character in the prefix | |
for(var i = 0; i < prefix.length; i++) { | |
// make sure prefix actually has words | |
if (node.children[prefix[i]]) { | |
node = node.children[prefix[i]]; | |
} else { | |
// there's none. just return it. | |
return output; | |
} | |
} | |
// recursively find all words in the node | |
findAllWords(node, output); | |
return output; | |
} | |
} | |
// recursive function to find all words in the given node. | |
function findAllWords(node, arr) { | |
if (node.end) { | |
arr.unshift({ word: node.getWord(), data: node.data }); | |
} | |
// iterate through each children, call findAllWords | |
for (var child in node.children) { | |
findAllWords(node.children[child], arr); | |
} | |
} | |
// // insert few values | |
// // check contains method | |
// console.log(trie.contains("helium")); // true | |
// console.log(trie.contains("kickass")); // false | |
// // check find method | |
// console.log(trie.find("hel")); // [ 'helium', 'hello' ] | |
// console.log(trie.find("hell")); // [ 'hello' ] | |
function filter(nodeList, fn) { | |
return Array.prototype.filter.call(nodeList, fn); | |
} | |
function process(xmlDoc) { | |
var trie = new Trie(); | |
const zipCodeNodes = filter(xmlDoc.children[0].childNodes, node => { | |
return node.nodeType === 1; | |
}); | |
zipCodeNodes | |
// .slice(0, 10) | |
.forEach(node => { | |
const dataNodes = filter(node.childNodes, node => { | |
return node.nodeType === 1; | |
}); | |
const code = dataNodes[0].childNodes[0].data; | |
const city = dataNodes[1].childNodes[0].data; | |
const state = dataNodes[2].childNodes[0].data; | |
trie.insert(city, { code, city, state }); | |
}) | |
root.innerHTML = searchUI(); | |
} | |
root.innerHTML = '<div class"loading">Fetching and loading data...</div>'; | |
fetch('/zipcode.xml').then(response => response.text()) | |
.then(str => (new window.DOMParser()).parseFromString(str, "text/xml")) | |
.then(process) | |
.catch(console.error); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment