#javascript #typescript #filter
Вопрос:
У меня есть тип объекта результата. Я хочу отфильтровать записи из объекта результата. У меня в форме есть 3 фильтра (Поиск по имени, городу, электронной почте). Все фильтры являются многовыборочными. Теперь я хочу отфильтровать свои записи результатов по приведенному выше массиву фильтров.
Пользователь отфильтрован по записям, использующим массив ниже
var searchByname = ['john', 'test1'];
var searchByEmail = ['john@gmail.com', 'test1@gmail.com'];
var searchByCity = ['CA', 'LA'];
Фактический объект результата, из которого должен быть выполнен фильтр
var result = [
{
'name': 'john',
'email': 'john@gmail.com',
'city': 'CA',
'phone': 425663313
},
{
'name': 'test1',
'email': 'test1@gmail.com',
'city': 'LA',
'phone': 7418669633
},
{
'name': 'Dyna',
'email': 'Dyna@gmail.com',
'city': 'New York',
'phone': 12345666
}
]
Я попробовал приведенное ниже решение, но оно фильтрует только любые записи одного фильтра
var filteredArray_1 = result.filter(function(itm){
return searchByname.indexOf(itm.name) > -1;
});
var filteredArray_2 = result.filter(function(itm){
return searchByEmail.indexOf(itm.email) > -1;
});
var filteredArray_3 = result.filter(function(itm){
return searchByCity.indexOf(itm.city) > -1;
});
let finalArray = [...filteredArray_1, ...filteredArray_2, ...filteredArray_3];
Ожидаемый Результат
var result = [
{
'name': 'john',
'email': 'john@gmail.com',
'city': 'CA',
'phone': 425663313
},
{
'name': 'test1',
'email': 'test1@gmail.com',
'city': 'LA',
'phone': 7418669633
},
]
Ответ №1:
Ваш фильтр включает результаты любого проходящего фильтра и может включать результаты дважды.
Вместо этого примените все свои фильтры вместе:
const searchByname = ['john', 'test1'];
const searchByEmail = ['john@gmail.com', 'test1@gmail.com'];
const searchByCity = ['CA', 'LA'];
const result = [
{
'name': 'john',
'email': 'john@gmail.com',
'city': 'CA',
'phone': 425663313
},
{
'name': 'test1',
'email': 'test1@gmail.com',
'city': 'LA',
'phone': 7418669633
},
{
'name': 'Dyna',
'email': 'Dyna@gmail.com',
'city': 'New York',
'phone': 12345666
},
undefined, // Dummy test empty
{ } // Dummy test with no properties
];
const multifiltered = result.
filter(itm => searchByname.indexOf(itm?.name) > -1).
filter(itm => searchByEmail.indexOf(itm?.email) > -1).
filter(itm => searchByCity.indexOf(itm?.city) > -1);
console.log('Multiple filters', multifiltered);
// However, your code will be easier to read if you do a single operation...
const filteredAND = result.
filter(itm =>
itm amp;amp;
searchByname.indexOf(itm.name) > -1 amp;amp;
searchByEmail.indexOf(itm.email) > -1 amp;amp;
searchByCity.indexOf(itm.city) > -1);
console.log('AND filters', filteredAND);
const filteredOR = result.
filter(itm =>
itm amp;amp; (
searchByname.indexOf(itm.name) > -1 ||
searchByEmail.indexOf(itm.email) > -1 ||
searchByCity.indexOf(itm.city) > -1));
console.log('OR filters', filteredOR);
Комментарии:
1. Дает ли это мне результат, если один из моих фильтров равен нулю?
2. @UserPHP Нет, но его легко добавить
item amp;amp; (...)
вокруг предложения3. Я не получаю возможность добавить его в текущий код
4. Фрагмент @UserPHP обновлен с проверками на пустоту
5. Из моих 3 фильтров, если только searchByname имеет значение, но два других не имеют никакого значения, они оба пусты, это работает?
Ответ №2:
Я не уверен, что полностью понимаю ваш вопрос.
но вы могли бы фильтровать таким образом
var filtered = result.filter(
(item) =>
searchByname.includes(item.name) ||
searchByEmail.includes(item.email) ||
searchByCity.includes(item.city)
);
Это даст вам желаемый результат
Ответ №3:
Вы можете попробовать все это в зависимости от ваших требований,
let andFiltered = result.filter(
(data) =>
searchByname.includes(data.name) amp;amp;
searchByEmail.includes(data.email) amp;amp;
searchByCity.includes(data.city)
);
console.log(andFiltered);
let orFiltered = result.filter(
(data) =>
searchByname.includes(data.name) ||
searchByEmail.includes(data.email) ||
searchByCity.includes(data.city)
);
console.log(orFiltered);