2016-06-04 6 views
-1

Ich habe diese Übung Baum, um den nächsten Buchstaben zurückzugeben, um Tipp für eine vereinfachte Suchleiste Feature vorschlagen, wo ich die WordTree.prototype.search Funktion implementieren muss. Hier ist die grundlegende Funktionalität:Array 'Ergebnis' ist ['o'] vor der Rückgabe. Nach der Rückkehr ist es []. Wie?

tree.search('Levi'); // returns [] (adds each letter) 
tree.search('Lego'); // returns [] 
tree.search('Le'); // returns ['g', 'v'], suggesting 'g' and 'v' from the previous entries 
tree.search('Leg'); // ['o'], suggesting 'o' from 'Lego' 

Der resultierende Baum sollte (mit einem console.log prüft) werden:

* * (root) 
    | 
    -- L 
    | 
    -- e 
     | 
     -- v 
     | | 
     | -- e 
     | | | 
     | | -- l 
     | | 
     | -- i 
     | 
     -- g 
      | 
      -- o 

Hier ist mein Code. Die letzte Zeile enthält den Test, der nicht funktioniert, sollte aber sein. Ich auch markiert mit ******* im Code, um zu zeigen, wo die result gleich ['o'] ist, aber wenn entweder zu dem Test oder dem console.log zurückgegeben wird, ist es []. Wie kann das passieren?

var expect = require('chai').expect; 

var Node = function(data) { 
    this.data = data; 
    this.children = []; 
}; 

var WordTree = function() { 
    var node = new Node({}); 
    this.root = node; 
}; 

WordTree.prototype.search = function(word, nodes) { 
// code starts here 
    var currentLetter = word.charAt(0); 

    if (nodes === undefined) { // if top-level search... 
    if(!containsLetter(this.root.children, currentLetter)) { 
     var newLetter = new Node(currentLetter); 
     this.root.children.push(newLetter); 
     this.search(word); // add the rest of the word 
     return []; 
    } else { // first letter exists, so let's begin search recursively 
     var nodeIndex = getNodeIndexWithLetter(this.root.children, currentLetter); 
     return this.search(word.slice(1), this.root.children[nodeIndex].children); 
    } 
    } else { // if 'nodes' is defined, we know recursion is going on 

    // if last letter in 'word', suggest the next possible words in the tree 
    if(word.length === 1){ 
     var result = []; 
     if(containsLetter(nodes, currentLetter)) { 
      var currLetterChildren = nodes[ getNodeIndexWithLetter(nodes, currentLetter) ].children; 
      result = currLetterChildren.map(function getChildrenData(childNode) { 
      return childNode.data; 
      }); 
      // console.log(result); // <--- *****THIS IS ['o'] **** 
      return result; // <---- BUT IT RETURNS []. 
     } else { 
      nodes.push(new Node(currentLetter)) 
     } 
     return result; 
     } 

     // if there are more letters to traverse... 
     if(!containsLetter(nodes, currentLetter)) { 
     var newLetter = new Node(currentLetter); 
     nodes.push(newLetter); 
     this.search(word.slice(1), newLetter.children); // add the rest of the word 
     } else { 
      this.search(word.slice(1), nodes[ getNodeIndexWithLetter(nodes, currentLetter)].children); 
     } 
     } 
     return []; 

     // these are O(n). Something to fix later 
     function containsLetter(childArray, num){ 
     var found = false; 
     childArray.forEach(function(child) { 
     if(child.data === num) 
      found = true; 
     }) 
     return found; 
     } 
     // O(n). Fix later. 
     function getNodeIndexWithLetter(nodeArray, num) { 
     var index = -1; 
     nodeArray.forEach(function(element, i) { 
      if(element.data === num) 
      index = i; 
     }) 
     return index; 
     } 
    }; 

    var tree = new WordTree(); 

    expect(tree.search('Levi')).to.deep.equal([]); 
    expect(tree.search('Level')).to.deep.equal([]); 
    expect(tree.search('Lego')).to.deep.equal([]); 
    expect(tree.search('Le')).to.deep.equal(['v', 'g']); 
    console.log(
    tree.search('Leg') 
); 
    // console.log(JSON.stringify(tree.root)); 
    // expect(tree.search('Leg')).to.deep.equal(['o']); // <-- something is off about this test 
+1

Verwenden Sie eine Debugger und das Problem eingrenzen – Amit

+0

Guter Vorschlag. Als ich nach Debuggern Ausschau hielt, entdeckte ich, dass ich zu viele 'result =' - Anweisungen habe, aber ich verstehe immer noch nicht, warum die return-Anweisung nicht einfach aus dem Callstack ausbricht. –

Antwort

0

Dies ist die korrigierte Version. Grundsätzlich habe ich gelernt Debug Node.js Programme mit node debug filename.js. Das Problem war, dass die rekursiven/verschachtelte return-Anweisungen gebrochen wurden und die search Funktion fortgesetzt in den äußeren Anrufen, bis zu einem Punkt zu gehen, wo das Ergebnis einer leeren Array []

var expect = require('chai').expect; 
 

 
var Node = function(data) { 
 
    this.data = data; 
 
    this.parent = null; 
 
    this.children = []; 
 
}; 
 

 
var WordTree = function() { 
 
    var node = new Node({}); 
 
    this.root = node; 
 
}; 
 

 
WordTree.prototype.search = function(word, nodes) { 
 
    // your code goes here 
 
    var currentLetter = word.charAt(0); 
 

 
    if (nodes === undefined) { // if top-level search... 
 
    if (!containsLetter(this.root.children, currentLetter)) { // if new word... 
 
     var newLetter = new Node(currentLetter); 
 
     this.root.children.push(newLetter); 
 
     this.search(word); // ... add the rest of the word... 
 
     return []; // ... and return nothing 
 
    } else { // first letter exists, so let's begin search recursively 
 
     var nodeIndex = getNodeIndexWithLetter(this.root.children, currentLetter); 
 
     return this.search(word.slice(1), this.root.children[nodeIndex].children); 
 
    } 
 

 
    } else { // if 'nodes' is defined, we know recursion is going on 
 

 
    // if we're in the last letter in 'word', suggest the next possible letters in the tree, if any 
 
    if (word.length === 1) { 
 
     if (containsLetter(nodes, currentLetter)) { 
 
     var currLetterChildren = nodes[getNodeIndexWithLetter(nodes, currentLetter)].children; 
 
     var result = currLetterChildren.map(function getChildrenData(childNode) { 
 
      return childNode.data; 
 
     }); 
 
     return result; 
 

 
     } else { // ... otherwise the last letter doesn't exist. Add it and return nothing 
 
     nodes.push(new Node(currentLetter)) 
 
     return []; 
 
     } 
 
    } 
 

 
    // if there are still multiple letters to traverse... 
 
    if (!containsLetter(nodes, currentLetter)) { // ... and a letter was not found... 
 
     var newLetter = new Node(currentLetter); 
 
     nodes.push(newLetter); 
 
     this.search(word.slice(1), newLetter.children); // ... add the rest of the word... 
 
     return []; // return nothing because a new letter in the tree means new word 
 
    } else { // ... if a letter was found we might possibly return something... 
 
     return this.search(word.slice(1), nodes[getNodeIndexWithLetter(nodes, currentLetter)].children); 
 
    } 
 
    } 
 

 
    // ** Utility functions below ** 
 
    // These are defined in the search function because they pertain to this function only 
 
    // No need to litter the global scope with utility functions 
 

 
    // These are O(n). Possibly something to fix later 
 
    function containsLetter(childArray, num) { 
 
     var found = false; 
 
     childArray.forEach(function(child) { 
 
     if (child.data === num) 
 
      found = true; 
 
     }) 
 
     return found; 
 
    } 
 
    // O(n). Fix later. 
 

 
    function getNodeIndexWithLetter(nodeArray, num) { 
 
    var index = -1; 
 
    nodeArray.forEach(function(element, i) { 
 
     if (element.data === num) 
 
     index = i; 
 
    }) 
 
    return index; 
 
    } 
 
}; 
 

 
var tree = new WordTree(); 
 

 
expect(tree.search('Levi')).to.deep.equal([]); 
 
expect(tree.search('Level')).to.deep.equal([]); 
 
expect(tree.search('Lego')).to.deep.equal([]); 
 
expect(tree.search('Le')).to.deep.equal(['v', 'g']); 
 
expect(tree.search('Leg')).to.deep.equal(['o']);
war

Verwandte Themen