#javascript
Вопрос:
Я пытаюсь создать функцию поиска. Количество фильтров будет динамически меняться, количество ключей может быть разным, и количество значений тоже.
Мой код выглядит так:
var data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Resla"}]
var keys = ["color", 'model'];
var values = ["Re"];
var result = data.filter(function(e) {
return keys.every(function(a) {
return values.includes(e[a])
})
})
console.log(result);
Можно ли выполнять поиск с помощью — StartsWith() и не включает()? Я думаю, что все также должно быть в нижнем регистре ()?
Также могу ли я получить два отдельных результата в виде двух массивов, если результаты найдены в одном ключе, то это должен быть отдельный массив? Таким образом, результаты будут такими:
[{ colors: [{"id":"123","color":"Red","model":"Tesla"},{"id":"125","color":"Red","model":"Audi"}], models: [{"id":"126","color":"Blue","model":"Resla" }] }]
Заранее большое вам спасибо.
Комментарии:
1. Вам, наверное, нужно
keys.some
и неevery
нужно . Кроме того, для тестирования вам нужно вложенноеvalues.some()
или регулярное выражение, разделенное|
2. спасибо @adiga Я действительно работаю над тем, чтобы это работало, не могли бы вы, пожалуйста, создать для меня пример кода?
Ответ №1:
Вы можете перебрать каждый ключ и значение и просмотреть их в массиве объектов, используя array#reduce
const data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Resla"}],
keys = ["color", 'model'],
values = ["Re"],
initial = Object.assign(...keys.map(k => ({[`${k}s`]: [] }))),
result = data.reduce((r, o) => {
keys.forEach(k => {
values.forEach(val => {
if(o[k] amp;amp; o[k].startsWith(val)) {
r[`${k}s`].push(o);
}
});
});
return r;
},initial);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Комментарии:
1. Привет @hassanimam Я действительно ценю ваш пример, который очень хорошо работает! Миллион раз спасибо!
Ответ №2:
- Вам нужно проверить
keys.some
и нетkeys.every
. Это позволит проверить, является ли значение частью хотя бы одного из ключей, а не всех из них. - Для значений можно создать динамическое регулярное выражение с чередованием и
test
значением по отношению к регулярному выражению. Итак,values = ["Re", "Ho"]
создадим/Re|Ho/
const data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Resla"}],
keys = ["color", 'model'],
values = ["Ho"],
regex = new RegExp(values.join('|')),
output = data.filter(e => keys.some(k => regex.test(e[k])) )
console.log(output);
Если вы хотите получить индивидуальные результаты для каждого ключа, вы можете просмотреть ключи и проверить регулярное выражение по отдельности.
const data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Resla"}],
keys = ["color", 'model'],
values = ["Ho", "Re"],
regex = new RegExp(values.join('|')),
group = {}
for (const o of data) {
for (const k of keys) {
if (regex.test(o[k])) {
group[k] ||= []
group[k].push(o)
}
}
}
console.log(group);