Я пытаюсь реализовать функцию поиска, которая возвращает поиск, который имеет поисковое слово в указанном массиве. Допустим, в коллекции есть [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

3 ответа

Если вы хотите искать совпадения только при заполнении соответствующего 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>

Вы можете использовать Array.filter () с Array.some () , а в обратном вызове some проверить, содержит ли строка строку поиска:

const students = [
  {
   name:'aa',
   searchWords:['aa','ab','bc']
  },
  {
   name:'bb',
   searchWords:['bb','bc','de'] 
  },
]

const searchName = 'e'
const result = students.filter(o => o.searchWords.some(
  w => w.includes(searchName)
))

console.log(result)

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

Кроме того, String # включает в себя :

filterStudents = students.filter(student =>
  student.tags.some((tag) => tag.includes(searchTag))
);
58583322