| 65 | } |
| 66 | |
| 67 | remove(word, count) { |
| 68 | if (typeof word !== 'string') return |
| 69 | if (typeof count !== 'number') count = 1 |
| 70 | else if (count <= 0) return |
| 71 | |
| 72 | // for empty string just delete count of root |
| 73 | if (word === '') { |
| 74 | if (this.root.count >= count) this.root.count -= count |
| 75 | else this.root.count = 0 |
| 76 | return |
| 77 | } |
| 78 | |
| 79 | let child = this.root |
| 80 | const len = word.length |
| 81 | let i, key |
| 82 | // child: node which is to be deleted |
| 83 | for (i = 0; i < len; i++) { |
| 84 | key = word.charAt(i) |
| 85 | if (child.children[key] === undefined) return |
| 86 | child = child.children[key] |
| 87 | } |
| 88 | |
| 89 | // Delete no of occurrences specified |
| 90 | if (child.count >= count) child.count -= count |
| 91 | else child.count = 0 |
| 92 | |
| 93 | // If some occurrences are left we don't delete it or else |
| 94 | // if the object forms some other objects prefix we don't delete it |
| 95 | // For checking an empty object |
| 96 | // https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object |
| 97 | if ( |
| 98 | child.count <= 0 && |
| 99 | Object.keys(child.children).length && |
| 100 | child.children.constructor === Object |
| 101 | ) { |
| 102 | child.parent.children[child.key] = undefined |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | findAllWords(prefix) { |
| 107 | const output = [] |