Сделать фильтрацию по элементам вложенного массива через поиск
Здравсвуйте! Помоги решить задачу: нужно сделать фильтрацию пользователей по тегам и имени через input. Данные по пользователю находятся во вложенном массиве. Код:
users = [
{name: 'Ivan', country: 'Russia', tags: ['Moscow', 'Man'], view: true},
{name: 'Luisa', country: 'Australia', tags: ['Sydney', 'Woman'], view: true},
];
TS:
getAdvancedSearchProperties(tags) {
this.propSearch = tags;
console.log('bbb', tags);
for (let i = 0; i < this.users.length; i++) {
if (this.users[i].name === 'Ivan') {
this.users[i].view = false;
} else {this.users[i].view = true; }
}
for (let i = 0; i < this.users.length; i++) {
if (this.users[i].tags === 'Moscow') {
this.users[i].view = false;
}
}
}
На данный момент поиск, при любом вводе, оставляется карточки с Иваном, а на хештеги вообще не реагирует Помогите решить проблему, пожалуйста!
Ответы (1 шт):
Ну начнём с того что алгоритм сразу скажем так не рассчитан на использование нескольких фильтров, второй цикл игнорирует результат фильтрации первого, да и сам способ фильтрации через параметр view скажем так не лучший вариант, при этом сравнение массива тэгов со строкой не имеет никакого смысла. Для решения таких задача обычно делают два массива, один с результатами фильтрации, а другой с исходными данными, пример:
const users = [
// Добавил общий тэг тоже для теста
{ name: 'Ivan', country: 'Russia', tags: ['Moscow', 'Man', 'Test'], view: true },
{ name: 'Luisa', country: 'Australia', tags: ['Sydney', 'Woman', 'Test'], view: true },
];
const updateView = (data) => {
window.users.innerHTML = data.map(({ name, country }) => `<h4>${name} - ${country}</h4>`).join('');
};
updateView(users);
const updateUsers = () => {
const inputValue = window.input.value;
const selectValue = window.select.value;
const filteredUsers = users
.filter(({ name }) =>
// Приводим к нижнем регистру для более лояльного к юзеру поиска
inputValue ? name.toLowerCase().match(inputValue.toLowerCase()) : true
)
// .includes метод массива проверяет если есть нужное значение в массиве, ну и сделал для теста пустой тэг None
.filter(({ tags }) => (selectValue && selectValue !== 'None' ? tags.includes(selectValue) : true));
updateView(filteredUsers);
};
<input id="input" oninput="updateUsers()" />
<select id="select" onchange="updateUsers()">
<option>None</option>
<option>Moscow</option>
<option>Man</option>
<option>Woman</option>
<option>Sydney</option>
<option>Test</option>
</select>
<br />
<div id="users"></div>