Tom Select реализует механизм сопоставления (matching) как комбинацию нормализации входной строки, разбиения на токены, вычисления взвешенного рейтинга релевантности и последующей сортировки результатов. Алгоритм оптимизирован под интерактивный ввод, где ключевым фактором становится не полнота поиска, а скорость реакции и предсказуемость ранжирования.
Перед тем как выполняется любое сравнение строк, входные данные проходят этап нормализации. Он включает:
Нормализация снижает энтропию данных и позволяет алгоритму
сопоставления работать стабильно вне зависимости от языка и способа
ввода. Например, строки Résumé, resume и
RESUME после обработки становятся эквивалентными.
Внутри системы сопоставления нормализуется как пользовательский ввод, так и значения элементов списка, что исключает асимметрию сравнения.
После нормализации выполняется разбиение строк на токены. Токенизация в Tom Select основана на разделении по пробелам и дополнительным разделителям (знаки препинания, дефисы, подчеркивания).
Пример:
"New York City" → ["new", "york", "city"]
Токены используются для:
Токенизация позволяет реализовать гибкое сопоставление, где порядок слов может быть нестрогим.
Ключевой элемент механизма — функция оценки релевантности (score). Для каждого элемента списка вычисляется числовое значение, отражающее степень соответствия запросу.
Общая идея:
score = Σ (matchWeight * fieldWeight)
Где:
matchWeight — степень совпадения конкретного поля или
токена;fieldWeight — вес поля, заданный конфигурацией.Чем выше итоговый score, тем выше позиция элемента в выдаче.
Если совпадений нет, элемент исключается из результата.
Параметр searchField определяет, какие поля объекта
участвуют в сопоставлении.
Пример структуры данных:
{
title: "JavaScript Developer",
company: "Tech Corp",
tags: "frontend js remote"
}
Конфигурация:
searchField: ["title", "company", "tags"]
Алгоритм:
Это позволяет реализовать многомерный поиск, где разные поля имеют разную семантическую значимость.
Помимо searchField, используется sortField,
который влияет на финальное ранжирование.
Пример:
sortField: [
{ field: "score", direction: "desc" },
{ field: "title", direction: "asc" }
]
Логика:
Внутри системы сортировки score всегда имеет приоритет, поскольку отражает качество совпадения.
Алгоритм сопоставления поддерживает несколько уровней совпадений:
Рейтинг уменьшается по мере удаления от полного совпадения. Например:
"react" > "react js" > "learn react tutorial" > "javascript framework react"
Хотя базовый алгоритм не является полноценным Levenshtein-фаззи поиском, он включает эвристики:
Это создаёт эффект «мягкого поиска», при котором:
Например:
"javscrpt" → может сопоставиться с "javascript"
через частичное совпадение токенов.
Обработка диакритических знаков — важный этап для многоязычных интерфейсов. Алгоритм приводит строки к базовой латинской форме:
"café" → "cafe"
"naïve" → "naive"
Это расширяет область совпадений без изменения исходных данных.
При необходимости поведение можно отключить для строго языковых сценариев, где диакритика семантически значима.
Tom Select позволяет переопределить стандартную логику сопоставления
через scoreFunction.
Сигнатура:
scoreFunction: function(search, option) {
return number;
}
Механика:
Это полностью заменяет стандартный алгоритм.
Пример расширенной логики:
scoreFunction: function(search, option) {
let score = 0;
if (option.title.includes(search)) score += 10;
if (option.tags.includes(search)) score += 5;
return score;
}
Такой подход позволяет внедрять доменно-специфичную релевантность.
Некоторые реализации используют порог отсечения (threshold), ниже которого элементы исключаются из выдачи.
Логика:
if (score < threshold) → исключить
Это предотвращает попадание нерелевантных элементов в список, особенно при больших наборах данных.
Алгоритм сопоставления оптимизирован под частые вызовы при вводе текста:
Дополнительно применяется debounce на уровне ввода, что снижает частоту пересчёта результатов при быстром наборе текста.
При значительных объёмах данных алгоритм использует:
Это позволяет сохранять интерактивную скорость даже при тысячах опций.
Хотя Tom Select не строит полноценный поисковый индекс, внутренняя структура данных может быть подготовлена заранее:
Это приближает поведение к легковесному in-memory search engine.
Алгоритм стремится обеспечить детерминированность:
Это исключает «прыгающие» результаты при повторных вычислениях.
При пустом вводе алгоритм:
Score в этом случае либо не вычисляется, либо считается равным базовому значению.
Такой режим используется для отображения «каталога по умолчанию» без активного поиска.