- ВКонтакте
- РћРТвЂВВВВВВВВнокласснРСвЂВВВВВВВВРєРСвЂВВВВВВВВ
- РњРѕР№ Р В Р’В Р РЋРЎв„ўР В Р’В Р РЋРІР‚ВВВВВВВВРЎР‚
- Viber
- Skype
- Telegram
Как отфильтровать массив по не точному поиску из другого массива?
Не получается отфильтровать массив по не точному соответствию из второго массива. Не получается убрать лишний данные.
const arr_1 = [
{name: 'Вася', age: 22},
{name: 'Петя', age: 23},
{name: 'Ваня', age: 22},
{name: 'Володя', age: 21},
]
const obj = {'тя', 'ня'}
const arr_2 = arr_1.filter(item => {
//Здесь код
}
console.log(arr_2)
На выходе должен получиться массив с удаленными данными
arr_2 = [
{name: 'Вася', age: 22},
{name: 'Володя', age: 21},
]
Ответы (2 шт):
Рассмотрим решение с временной сложностью O(n×m)
, где n - кол-во словарей в коллекции, m - медианная длина строки.
По идее, endsWith
, который будет использоваться ниже, имеет достаточно оптимизированное суффиксное дерево со сжатым бором, поэтому скорость должна быть вполне удовлетворительной, скорее даже O(n+m)
(если вообще нужна скорость)
Алгоритм будет следующим:
- Пройдем по ключам словарей и возьмем только строковые значения.
- Для поиска заданных строк используем метод
endsWith
и формулируем условие равенства для заданных подстрок. - Для сохранения компактности кода обернем метод
endsWith
в тест для проверки сформулированного условияsome
.
Полученный код:
const values = [
{name: 'Вася', age: 22},
{name: 'Петя', age: 23},
{name: 'Ваня', age: 22},
{name: 'Володя', age: 21},
]
const excludeVars = ['тя', 'ня'];
const out = values.filter(item => {
for (const key in item) {
const value = item[key];
if (typeof value === 'string' && excludeVars.some(vars => value.endsWith(vars))) {
return false;
}
}
return true;
});
console.log(out);
сам фильтр должен уметь отработать по любому значению ['ет', 'оно', 'в']. скорее что-то ближе к arr.includes(txt) должно отрабатывать. Но не получается все корректно обернуть с учетом единого регистра
Предложу такой вариант...
const arr = [
{name: 'Вася', age: 22},
{name: 'Петя', age: 23},
{name: 'Ваня', age: 22},
{name: 'Володя', age: 21},
]
const ex = ['тя', 'ня'].map(v => new RegExp(v, 'i'));
const res = arr.filter(s => !ex.some(r => r.test(s.name)))
console.log(res)
Или вообще вот так...
const arr = [
{name: 'Вася', age: 22},
{name: 'Петя', age: 23},
{name: 'Ваня', age: 22},
{name: 'Володя', age: 21},
]
const ex = new RegExp(['тя', 'ня'].join('|'), 'i');
const res = arr.filter(s => !ex.test(s.name))
console.log(res)