Вход

Просмотр полной версии : Как оптимизировать функцию фильтрации массива по вхождению?


dc65k
18.08.2022, 13:38
Всем привет. Исходный массив:

let arr = [
{
id: 1,
firstName: 'John',
lastName: 'Smith'
},
{
id: 2,
firstName: 'Brady',
lastName: 'Dennis'
},
{
id: 3,
firstName: 'Sandoval',
lastName: 'Pratt'
},
{
id: 4,
firstName: 'Davis',
lastName: 'Andrews'
}
]


Свойства, по которым нужно отфильтровать:

const filterBy = ['firstName', 'lastName'];

Вхождения (условия) по которым фильтруем:

const filterVal = ['joh', 'den'];


Результат:

/*
output
[
{ id: 1, firstName: 'John', lastName: 'Smith' },
{ id: 2, firstName: 'Brady', lastName: 'Dennis' }
]

*/


Решение:

function solution(a) {
return a.filter(item => {
return filterBy.some(prop => {
return filterVal.some(i => {
return item[prop].toLowerCase().includes(i)
})
})
})
}

console.log(solution(arr));


Решение в плане сложности алгоритма не оптимальное. Подскажите, пожалуйста, как его оптимизировать?

Vlasenko Fedor
18.08.2022, 16:28
const arrayFilter = (arr, rules) => arr.filter(el => Object.keys(rules).some(key => rules[key](el[key])));
const rules = {
firstName: v => v.toLowerCase().includes('joh'),
lastName: v => v.toLowerCase().includes('den'),
};

console.log(arrayFilter(arr, rules));
:) Вариант
const rules = {
firstName: v => /joh/i.test(v),
lastName: v => /den/i.test(v),
};

Aetae
18.08.2022, 16:37
Вполне себе оптимальное. Перебирается ровно столько сколько нужно.
Разве что вынести значение в переменную, чтоб лишний раз toLowerCase не делать: function solution(a) {
return a.filter(item => filterBy.some(prop => {
const value = item[prop].toLowerCase();
return filterVal.some(i => value.includes(i));
}));
}

console.log(solution(arr));