Механизм подбора подсказок в Awesomplete основан на разделении двух
ключевых этапов: фильтрации данных и ранжирования
результатов. Базовая реализация использует простое сопоставление по
началу строки, однако внутренняя архитектура допускает полную замену
алгоритма фильтрации через параметр filter.
Фильтрация в контексте автодополнения рассматривается как функция:
При этом библиотека не ограничивает форму элементов: это могут быть строки, массивы, объекты с метаданными.
Стандартная реализация фильтрации в Awesomplete ориентирована на префиксное совпадение:
toLowerCase()Упрощённая логика:
input → строка вводаitem → элемент спискаitem.indexOf(input) === 0Такой подход обеспечивает высокую производительность, но накладывает ограничения:
В Awesomplete фильтрация инкапсулирована и может быть переопределена
через свойство filter:
new Awesomplete(input, {
list: [...],
filter: function(text, input) {
return text.includes(input);
}
});
Данная точка расширения превращает библиотеку из фиксированного инструмента в платформу для построения собственных алгоритмов поиска.
Фильтр получает два аргумента:
text — элемент списка (или его отображаемое
значение)input — текущий запрос пользователяВозвращаемое значение — булево.
Одно из наиболее частых расширений — переход от префиксного поиска к поиску по подстроке.
filter: function(text, input) {
return text.toLowerCase().includes(input.toLowerCase());
}
Такой подход особенно полезен для:
Однако он ухудшает релевантность без дополнительного ранжирования.
Расширенные алгоритмы фильтрации в Awesomplete почти всегда требуют предварительной нормализации входных данных.
Пример:
function normalize(str) {
return str
.toLowerCase()
.trim();
}
Расширенная версия с поддержкой диакритики:
function normalize(str) {
return str
.toLowerCase()
.normalize("NFD")
.replace(/\p{Diacritic}/gu, "");
}
Токенизация позволяет разбивать строку на смысловые единицы и сравнивать их независимо.
function tokenize(str) {
return str.toLowerCase().split(/\s+/);
}
filter: function(text, input) {
const textTokens = tokenize(text);
const inputTokens = tokenize(input);
return inputTokens.every(t =>
textTokens.some(word => word.includes(t))
);
}
Одним из наиболее мощных расширений для Awesomplete является внедрение fuzzy-поиска.
Совпадение допускается даже при наличии:
function fuzzyMatch(text, input) {
let i = 0;
for (let char of text) {
if (char === input[i]) i++;
if (i === input.length) return true;
}
return false;
}
В продвинутых системах используется расстояние Левенштейна, позволяющее оценивать «стоимость» преобразования одной строки в другую.
В базовой модели фильтр возвращает true/false, однако
расширенные алгоритмы заменяют его на систему баллов.
function score(text, input) {
text = text.toLowerCase();
input = input.toLowerCase();
if (text.startsWith(input)) return 100;
if (text.includes(input)) return 50;
return 0;
}
list
.map(item => ({
item,
score: score(item, input)
}))
.filter(x => x.score > 0)
.sort((a, b) => b.score - a.score);
Такой подход значительно повышает качество подсказок по сравнению с бинарной фильтрацией.
Awesomplete допускает использование объектов в списке, что открывает возможность фильтрации по нескольким атрибутам.
[
{ label: "JavaScript", category: "language" },
{ label: "Java", category: "language" },
{ label: "Node.js", category: "runtime" }
]
filter: function(item, input) {
const query = input.toLowerCase();
return (
item.label.toLowerCase().includes(query) ||
item.category.toLowerCase().includes(query)
);
}
Фильтрация и сортировка в расширенных алгоритмах рассматриваются как единый pipeline.
maxResults = 10;
Даже при большом количестве совпадений интерфейс автодополнения должен оставаться компактным.
При использовании сложных алгоритмов фильтрации в Awesomplete важно учитывать нагрузку на ввод пользователя.
1. Кэширование нормализованных строк
2. Debouncing внешнего ввода
3. Предвычисление токенов
4. Ограничение длины запроса
На практике наиболее эффективные системы используют гибридный подход.
function hybridScore(text, input) {
const t = text.toLowerCase();
const i = input.toLowerCase();
if (t.startsWith(i)) return 3;
if (t.includes(i)) return 2;
if (fuzzyMatch(t, i)) return 1;
return 0;
}
В архитектуре Awesomplete фильтрация может быть полностью вынесена на сервер.
Расширенные алгоритмы фильтрации в Awesomplete формируют многоуровневую систему:
Такая архитектура превращает простую функцию поиска в адаптивный механизм, способный подстраиваться под тип данных, контекст ввода и требования интерфейса.