Я сейчас использую 1 tr ie для автозаполнения. Однако это работает, только если строка имеет тот же начальный символ, что и первый символ, как tr ie. ie, при наборе santa
отобразится santa clara
, но при наборе clara
в поле ввода этот результат (santa clara
) не отображается.
Как изменить код для использования 2 попыток - одна для автозаполнения списка слов и одна для автозаполнения для списка символов? Например, если бы я набрал clara
в поле ввода, результаты santa clara
по-прежнему отображаются?
//create node to be used to form a trie
class Node {
constructor(value = '') {
this.value = value;
this.children = [];
}
}
//class Trie
class Trie {
constructor() {
this.root = new Node();
}
add(value, parent = this.root) {
for (let i = 0, len = value.length; i < len; i++) {
let node = parent.children.find(child => child.value[i].toLowerCase() === value[i].toLowerCase());
if (!node) {
node = new Node(value.slice(0, i + 1).toLowerCase()); //slice from 0 to i
//console.log(node);
parent.children.push(node);
}
parent = node;
}
return parent;
}
find(value, parent = this.root) {
for (let i = 0, len = value.length; i < len; i++) {
parent = parent.children.find(child => child.value[i].toLowerCase() === value[i].toLowerCase());
if(!parent) return null;
}
return parent;
}
findWords(value, parent = this.root) {
let top = this.find(value, parent);
if (!top) return [];
let words = [];
top.children.forEach(function getWords(node) {
if (!node.children.length) words.push(node);
node.children.forEach(getWords);
});
return words;
}
createTrieFromArray(inputArr) {
for (let item of inputArr) {
let node = this.add(item);
node.item = item;
}
}
}
const trie = new Trie();
const data = [
"anaheim",
"Agoura Hills",
"Agua Dulce",
"Aguanga",
"Acalanes Ridge",
"Acampo",
"Acton",
"Adelanto",
"Adin",
"san antonio",
"san angelo",
"san diego",
"san jose",
"san jacinto",
"san francisco",
"san bernardino",
"san buenaventura",
"san bruno",
"san mateo",
"san marcos",
"san leandro",
"san luis obispo",
"san ramon",
"san rafael",
"san clemente",
"san gabriel",
"santa ana",
"santa clarita",
"santa clara",
"santa cruz",
"santa rosa",
"santa maria",
"santa monica",
"santa barbara",
"santa fe",
"santee",
"sandy",
"sandy springs",
"sanford"
];
trie.createTrieFromArray(data);
//console.log(trie);
const input = document.querySelector('input');
const results = document.querySelector('#results');
input.addEventListener('keyup', (e) => {
console.log(trie);
let resultList='';
const nodes = trie.findWords(e.target.value); // << Change
console.log(e.target.value, 'nodes ', nodes);
if (!nodes || !nodes.length) return; // << Change
for (let node of nodes) { // << Change
const category = node.category ? `- ${node.category}` : '';
let oneResult = `<li>${node.value} ${category}</li>`;
console.log(oneResult);
resultList += oneResult;
}
results.innerHTML = resultList;
});
input.addEventListener('keydown', e => {
// Tab Key
if (e.keyCode === 9) {
e.preventDefault();
const current = trie.find(input.value);
if (!current.children.length) return;
input.value = current.children[0].value;
}
});