У меня есть виджет заголовка, чтобы получить население штата или города в зависимости от того, что пользователь печатает
Вместо того, чтобы выдавать запрос GET каждый раз, когда пользователь заканчивает печатать, способ, которым работает этот виджет заголовка, - это выборка данных. заранее и сохраняя его в памяти и каждый раз, когда пользователь вводит данные, мы перебираем данные, чтобы получить то, что нам нужно.
Демонстрационная версия здесь: https://codesandbox.io/s/saveddatatypeahead-lcyfg?file= / src / index. js
Таким образом, данные извлекаются следующим образом
const data = [];
fetch(endpoint)
.then(res => res.json())
.then(result => {
data.push(...result);
});
, и мы слушаем событие input
в поле ввода, timeId
предназначено для отмены поиска мы не хотим искать слишком часто
searchInput.addEventListener("input", e => {
if (e.target.value.length > 2) {
if (timeId) {
clearTimeout(timeId);
}
timeId = setTimeout(() => {
displayMatches(e.target.value);
}, 500);
}
});
, и поиск выполняется здесь
function findMatches(regex, data) {
// the time complexity is
// O(M x K)
// M is the length of a city or state
// K is the keyword to match
// e.g. M - 'New York' K - 'yo'
return data.filter(
place => place.city.match(regex) || place.state.match(regex)
);
}
Здесь регулярное выражение построено на основе того, что пользователь ввел const regex = new RegExp(text, "ig");
На данный момент мне кажется, что сложность поиска здесь O(N x M x K)
N
- это количество записей в массиве data
, M
- средняя длина каждого города или штата. имя и K
Ключевое слово, введенное пользователем.
Итак, мой вопрос: Есть ли способ сделать поиск более эффективным? На данный момент я сделал две вещи, чтобы повысить эффективность.
1.Если пользователь вводит менее 3 символов, мы не выполняем поиск
2. отменяем поиск и запускаем его только после того, как пользователь закончит ввод
Правильно, объем данных невелик, но я вижу, что он плохо масштабируется при такой наивной реализации поиска. Может быть, строительство TR ie может помочь? Я не уверен.
Также приветствуются любые другие предложения и критические замечания по поводу этого виджета