Пользователям разрешено искать свои данные, вводя имя, город или код. Как я могу отобразить соответствующий объект в верхней части раскрывающегося списка.
Приоритизация Code здесь, так как когда пользователь вводит JOH, будет выделен следующий объект.
{
name: 'John Cena',
code: 'JOH',
city: 'California'
}
Код ниже работает, только если пользователь вводит полное имя, код или город. В списке более 1000 записей.
Попытка сначала сопоставить 3 символа code с введенным пользователем или иным образом по имени или городу.
let input = e.currentTarget.value;
const arr = []
for (const user of List) {
if (user.code.includes(input) > -1) {
arr.push(station)
}
}
}
Я имел в виду, когда пользователь вводит от 5 до 6 символов, фильтр отображает соответствующий объект. В коде всего 3 символа, поэтому я пытаюсь сопоставить код с кодом пользовательского ввода.
user.code.toLowerCase().includes(input) || user.city.toLowerCase().includes(input) || user.name.toLowerCase().includes(input)Ваш код также найдет ввод joh, но приоритезации нет. Таким образом, совпадения просто возвращаются в том порядке, в котором они появляются в userList
Я бы использовал библиотеку нечеткого поиска, например fuse.js
includes возвращает true или false сравнение с 1 не имеет смысла. if (user.code.includes(input)) достаточно



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если вам также нужен какой-то приоритет (например, совпадение в code имеет большее значение, чем совпадение в name), вам нужно будет взвесить каждое совпадение, а затем отсортировать по весу. Предполагая, что userList является массивом
let results = userList.map(user => {
let weight = 0;
if (user.code.toLowerCase().includes(input)) weight = 900
else if (user.name.toLowerCase().includes(input)) weight = 800
else if (user.city.toLowerCase().includes(input)) weight = 700
return { user, weight };
})
.filter(x => x.weight > 0)
.sort((a,b) => b.weight - a.weight)
.map(x => x.user);
Это сначала вернет список пользователей, отсортированных по наилучшему совпадению (т.е. совпадению по code). Это не очень эффективно, так как он просматривает список несколько раз, но на самом деле я не думаю, что это будет реальной проблемой всего с 1000 элементами...
Если у вас возникнут проблемы с производительностью, вы можете, например, преобразовать userlist.map(...).filter(...) в userlist.reduce(), но я оставляю это на ваше усмотрение... Для понимания решения я думаю, что map и filter легче читать.
Мне нравится идея weight здесь... +1
Протестировал ваше решение здесь ;) Предлагаю использовать его для добавления фрагмента.
И если я просто отфильтрую первые 20 списков на основе каждого нажатия клавиши, т.е. если результаты?.length >= 20 break.
.map(x => x.user).slice(0,20); даст наилучшие результаты. Спасибо.
Код ниже работает, только если я ввожу полностью - что?