Я пытаюсь реализовать функцию поиска, которая возвращает поиск, в котором есть поисковое слово в указанном массиве. Скажем, в коллекции есть [aa, ab, aaa], а поисковое слово - «a». В этом случае верните объект для отображения. Поскольку по крайней мере одна из строк в массиве имеет "a".

Структура данных

[
  {
   name:'aa',
   searchWords:['aa','ab','bc'] <- I want to use this array for search
  },
  {
   name:'bb',
   searchWords:['bb','bc','de'] <- I want to use this array for search
  },
...
]

Я попытался решить проблему с помощью include (), filter (), indexOf (). Однако он по-прежнему ничего не возвращает или возвращает данные, когда поисковое слово точно совпадает. Как исправить код для достижения прицеливания? Заранее спасибо!

эта часть работает хорошо

let filterStudents = students;
if (searchName.length > 0 && searchTag.length === 0) {
  filterStudents = students.filter((student) => {
    if (
      student.firstName.toLowerCase().includes(searchName.toLowerCase())
      || student.lastName.toLowerCase().includes(searchName.toLowerCase())
    ) {
      return true;
    }
    return false;
  });

Проблема возникает в этой части

} else if (searchName.length === 0 && searchTag.length > 0) {
  filterStudents = students.filter(
    (student) => {
      console.log(student.tags);
      student.tags.filter((tag) => {
        console.log(tag);
        tag.indexOf(searchTag) > -1;
      });
    },
  );
} else if (searchName.length > 0 && searchTag.length > 0) {
} else {
  console.log('both');
}
1
ShinCat 27 Окт 2019 в 23:57
Отсутствует return.
 – 
Jonas Wilms
28 Окт 2019 в 00:05

2 ответа

Вы не return из обратных вызовов filter

В качестве примечания есть также String#includes:

filterStudents = students.filter(student =>
  student.tags.some((tag) => tag.includes(searchTag))
);
0
Jonas Wilms 28 Окт 2019 в 00:06
Спасибо за ваш комментарий. Я последовал совету по этому коду. Однако это все еще не работает. иначе, если (searchName.length === 0 && searchTag.length> 0) {filterStudents = student.filter ((student) => student.tags.some ((tag) => tag.includes (searchTag)));
 – 
ShinCat
28 Окт 2019 в 00:28
Извините. Я просто нахожу решение. добавление .toLowerCase () заставляет этот поиск работать. filterStudents = student.filter ((student) => student.tags.some ((tag) => tag.includes (searchTag.toLowerCase ())));
 – 
ShinCat
28 Окт 2019 в 00:31

Если вы хотите искать совпадения только тогда, когда соответствующие searchTag или searchName заполнены, используйте условный оператор внутри обратного вызова filter, чтобы проверить, следует ли выполнять проверку фильтра:

const students = [
  {
   name:'aa',
   searchWords:['aa','ab','bc']
  },
  {
   name:'bb',
   searchWords:['bb','bc','de']
  },
];
const doFilter = () => {
  const [searchName, searchTag] = [...document.querySelectorAll('input')]
    .map(input => input.value.toLowerCase());
  const filtered = students.filter(({ name, searchWords }) => (
    (searchName ? name.toLowerCase().includes(searchName) : true) &&
    (searchTag ? searchWords.some(word => word.toLowerCase().includes(searchTag)) : true)
  ));
  code.textContent = JSON.stringify(filtered);
};

window.addEventListener('change', doFilter);
<input placeholder="searchName">
<input placeholder="searchTag">
<div>
  <code id="code"></code>
</div>
0
CertainPerformance 28 Окт 2019 в 00:08
Спасибо за ваш комментарий. Это правильный путь. У меня есть вопрос, и у меня есть четыре условия, которые возникают из комбинации True и False для имени и тега. В таком случае, следует ли мне пойти по этому пути?
 – 
ShinCat
28 Окт 2019 в 00:26
Например, помимо проверки того, имеют ли строки поиска длину, вы также хотите проверить включение или проверить отрицание обеих строк? В этот момент это слишком много, чтобы поместиться в одно выражение обратного вызова для чтения - лучше сначала поместить два теста в переменные, а затем вернуть переменные или их отрицания, условно, на основе этих других флагов
 – 
CertainPerformance
28 Окт 2019 в 00:29
RE: ваш удаленный комментарий, который уже присутствует в ответе - searchWords.some(word => word.toLowerCase().includes(searchTag)), где searchTag уже в нижнем регистре (см. Обратный вызов .map)
 – 
CertainPerformance
28 Окт 2019 в 00:31