Поиск по нескольким ключам и значениям, Javascript

#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);