Поиск массива по всем свойствам

Пользователям разрешено искать свои данные, вводя имя, город или код. Как я могу отобразить соответствующий объект в верхней части раскрывающегося списка.

Приоритизация 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)
        }
    
  }
}

Код ниже работает, только если я ввожу полностью - что?

Konrad 14.01.2023 17:22

Я имел в виду, когда пользователь вводит от 5 до 6 символов, фильтр отображает соответствующий объект. В коде всего 3 символа, поэтому я пытаюсь сопоставить код с кодом пользовательского ввода.

Bhoklu Singh 14.01.2023 17:24
user.code.toLowerCase().includes(input) || user.city.toLowerCase().includes(input) || user.name.toLowerCase().includes(input)
Konrad 14.01.2023 17:26

Ваш код также найдет ввод joh, но приоритезации нет. Таким образом, совпадения просто возвращаются в том порядке, в котором они появляются в userList

derpirscher 14.01.2023 17:26

Я бы использовал библиотеку нечеткого поиска, например fuse.js

Konrad 14.01.2023 17:26
includes возвращает true или false сравнение с 1 не имеет смысла. if (user.code.includes(input)) достаточно
Konrad 15.01.2023 12:27
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
6
88
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вам также нужен какой-то приоритет (например, совпадение в 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

Louys Patrice Bessette 14.01.2023 17:48

Протестировал ваше решение здесь ;) Предлагаю использовать его для добавления фрагмента.

Louys Patrice Bessette 14.01.2023 18:16

И если я просто отфильтрую первые 20 списков на основе каждого нажатия клавиши, т.е. если результаты?.length >= 20 break.

Bhoklu Singh 14.01.2023 19:58

.map(x => x.user).slice(0,20); даст наилучшие результаты. Спасибо.

Bhoklu Singh 14.01.2023 20:12

Другие вопросы по теме

Невозможно предотвратить повторный рендеринг Flatlist (уже используется useCallback и памятка)
Как отобразить другой заголовок в модальном окне, щелкнув определенный элемент среди множества вариантов?
Ошибка: гидратация не удалась, поскольку исходный пользовательский интерфейс не соответствует тому, что было отображено на сервере при использовании элемента Link
Прокрутка переполнения не работает в React Native
Получение неверного запроса с сервера (загрузка Spring) при использовании запроса axios
Как изменить цвет эффекта наведения в параметрах компонента выбора пользовательского интерфейса материала в реакции js?
Консоль NextJS регистрирует TypeError на консоли каждый раз, когда я делаю запрос на локальном хосте: не удается прочитать свойства неопределенного (чтение «_owner»)
Я хочу выбрать несколько раскрывающихся материалов в списке таблиц
База данных Firebase Realtime «Firebase: необходимо предоставить параметры, если они не развернуты на хостинге через источник»
Как организовать срезы в Redux Toolkit?