JavaScript Javascript: Find exactly 10 words in a prefix tree that start with a given prefix

I have a trie (also called a prefix tree). Given a prefix, I want to get a list of ten words that start with the prefix.

The thing that's unique about this problem is that I only want 10 of the words that start with the given prefix-- not all of them. There are optimizations that can be made, given this.

My code below I know works fine. Each node in the trie has a children property and a this_is_the_end_of_a_word property. For instance, when you insert "hi", this is what the trie looks like:

trie.

The problem: Given a prefix, I want to get a list of ten words that start with the prefix.

My approach to the problem was this: Head down the prefix tree, following the characters of prefix until you get to node which corresponds to the last character of prefix. Now you should perform a DFS on this node, keeping track of nodes that have this_is_the_end_of_a_word === true in a list. But you should stop searching when the length of your list is equal to 10, and return the list.

I think my approach is sound, but I'm having trouble implementing it-- particularly because I'm trying to use a recursive DFS, so I'm not sure how to pass the the "global" list around between the recursive calls. I know I should use closures, but I'm new to javascript and I'm unsure about how to go about it. An example of what I tried already is below.

My Trie class (I know this code works, this is just so you can see how I organized my data structure.)

var Trie = function() {

    var that = Object.create(Trie.prototype);
    that.children = {}; //mapping: next character -> child nodes
    that.this_is_the_end_of_a_word = false;

    that.insertWord = function(word) {

        var current_node = that;

        for (var i = 0; i < word.length; i++) {
            var c = word[i]
                //if character is not in the trie already, add it
            if (!(c in current_node.children)) {
                current_node.children[c] = Trie();
            }
            //update current_node
            current_node = current_node.children[c];
        };

        //after adding all the chars of the word, 
        //you are at the end of a word
        current_node.this_is_the_end_of_a_word = true;
    }

    that.insertWords = function(words) {
        for (var i = 0; i < words.length; i++) {
            that.insertWord(words[i]);
        }
    }

    that.contains = function(word) {
        //start at the root
        var current_node = that;
        for (var i = 0; i < word.length; i++) {
            var c = word[i];

            //if the word's character isn't a child of the current_node, 
            //the word isn't in the trie
            if (!(c in current_node.children)) {
                return false;
            }
            //move down the trie, update current_node
            current_node = current_node.children[c];
        };
        return current_node.this_is_the_end_of_a_word;
    }

    Object.freeze(that);
    return that;
}

My 1st approach (has many bugs)

num_words_to_go = 10; 
//this global is bad practice; 
//I want to put this as the argument to a closure 
//so it's passed between recursive calls

that.getWords = function(start_node, prefix) {
   console.log(0);
   var words = [];

   //if start node is a word, add it
   if (start_node.this_is_the_end_of_a_word) {
       words.push(start_node);
       num_words_to_go--;
   }

   if (num_words_to_go <= 0 || !start_node.children) {
       return words;
   }

   return start_node.children.forEach(
                              currentValue.getWords(
                                    currentValue, prefix + <character for this child>)); 

   /*I can't think of a nice way to write this without going through all of the children. 
   I know I don't need to, because I only need to find 10 words and get out. 
   This is why I was leaning towards the recursive DFS. 
   */

}

2nd approach: I also found a python example that I was looking at: http://v1v3kn.tumblr.com/post/18238156967/roll-your-own-autocomplete-solution-using-tries I tried translating his example to JavaScript, but still something's going wrong with all_suffixes.

that.all_suffixes = function (prefix){
    results = [];
    if (that.this_is_the_end_of_a_word) results.push(prefix);
    if (!(that.children)) return results;
    if (results.length > 2) return results;
    var callback = function(currentValue, i, array){
        return currentValue.all_suffixes(prefix+array[i]);
    }
    arr = that.children.forEach(callback, that);
        //[child.all_suffixes(prefix + char) for (char, child) in self.children.items()]
    return concat(reduce(concat, arr), results);        
}

 that.autocomplete = function(prefix){
    current_node = that;
    for(var i = 0; i < prefix.length; i++){
        var c = prefix[i];
        //if there is nothing in the trie with this prefix
        if (!(c in current_node.children)){
            return [];
        }
        current_node = current_node.children[c];
    }
    return list(current_node.all_suffixes(prefix))
 }
Answer:1

I'm trying to get data from a server in my AngularJS app, using $http.get. But when I execute the request, it seems to get cancelled by something. It happens with every link I use. Local files are ...

I'm trying to get data from a server in my AngularJS app, using $http.get. But when I execute the request, it seems to get cancelled by something. It happens with every link I use. Local files are ...

  1. angularjs http request
  2. angularjs http request example
  3. angularjs http request timeout
  4. angularjs http request default timeout
  5. angularjs http request headers
  6. angularjs http request in loop
  7. angularjs http request interceptor example
  8. angularjs http request interceptor
  9. angularjs http request progress bar
  10. angularjs http request error handling
  11. angularjs http request synchronous
  12. angularjs http request parameters
  13. angularjs http request cors
  14. angularjs http request body
  15. angularjs http request json
  16. angularjs http request multipart/form-data
  17. angularjs http request cross domain
  18. angularjs http request method options
  19. angularjs http request content type
  20. angularjs http request form data

So I can create a whole bunch of empty objects that are independent with my code below. Is there a better way to do this? Or is this the only method? var array = []; for (let i = 0; i < 5; ...

So I can create a whole bunch of empty objects that are independent with my code below. Is there a better way to do this? Or is this the only method? var array = []; for (let i = 0; i < 5; ...

Here is my setup. I have a grunt task that does 2 things: 1) start a http server listening on some port 2) triggers another grunt task The grunt task triggered above is a testem task that runs tests ...

Here is my setup. I have a grunt task that does 2 things: 1) start a http server listening on some port 2) triggers another grunt task The grunt task triggered above is a testem task that runs tests ...

  1. post call from browser
  2. post call from javascript
  3. post call from java
  4. post call from postman
  5. post call from angular
  6. post call from python
  7. post call from c#
  8. post call from react
  9. post call from jquery
  10. post call from php
  11. post call from curl
  12. post call from html
  13. post call from node js
  14. post call from js
  15. post call in react js
  16. post call from angular 7
  17. post call from ajax
  18. post call from react js
  19. post call from angularjs
  20. post call in angular 6

I'm doing an example for this javascript textbook and it's a simple calculator. There are two input (number) tags where the user selects a number and a select tag with options for a modifier (see code)...

I'm doing an example for this javascript textbook and it's a simple calculator. There are two input (number) tags where the user selects a number and a select tag with options for a modifier (see code)...

  1. value option select jquery
  2. value option select
  3. value option select html
  4. value option select javascript
  5. value option select php
  6. option value select all
  7. option value select default
  8. value select option angular
  9. option value select js
  10. value select option angularjs
  11. option value select tag
  12. option value select name
  13. option value select disabled
  14. option value select input
  15. set value option select jquery
  16. get value option select jquery
  17. change value option select jquery
  18. set value option select javascript
  19. get selected option value
  20. get value option select javascript