Фильтрация массива объекта другим массивом объектов

Есть массив объектов:

arr1 = [
    {"type": 1, "check": true},
    {"type": 2, "check": false},
    {"type": 2, "check": false},
    {"type": 3, "check": false}
]

Его нужно отфильтровать другим массивом, в котором указан параметр фильтрации и значение

arr2 = [
   {"param": "type", "value": [1, 2]},
   {"param": "check", "value": true},
]

Но массив arr2 может вообще не содержать данных или содержать не все, т.е. может быть: arr2 = [] или

arr2 = [
   {"param": "type", "value": [1, 2]}
]

или

arr2 = [
   {"param": "check", "value": true}
]

Ответы (1 шт):

Автор решения: stylok

С учётом дублируемых ключей в первом массиве, и особенно из-за того, что другой массив может представлять из себя "что угодно" вам так или иначе придётся обозначить все эти условия фильтрации и никак иначе. Думаю, что за основу обработки лучше всего воспользоваться reduce

const result = arr1.reduce((acc,item) => {
  // условия
  return acc
}, []);

А с учётом наличия массивов значений в arr2, дабы избежать излишней вложенности обработки и путаницы я бы предложил разделить на два этапа. Сначала собрать ключи для обработки, а уж потом получать результат.

const arr1 = [
  {"type": 1, "check": true},
  {"type": 2, "check": false},
  {"type": 2, "check": false},
  {"type": 3, "check": false}
]
const arr2 = [
  {"param": "type", "value": [1, 2]},
  {"param": "check", "value": true},
]

// 1 этап
const keys = arr2.reduce((acc,item) => {
  if (Array.isArray(item.value)) {
    item.value.forEach(i => {
      // клонируем ключ, чтобы не мудрить с созданием нового
      const clone = structuredClone(item);
      clone.value = i;
      acc.push(clone);
    });
  } else {
    acc.push(item);
  }
  return acc
},[]);
console.log('keys:\n', keys);

// 2 этап
const result = keys.reduce((acc,key) => {
  const re = arr1.reduce((a,k) => {
    // одно условие или добавить другие на свой вкус.
    if (key.param in k && key.value === k[key.param]) {
      a.push(key)
    }
    return a
  },[]);
  acc = acc.concat(re);
  return acc
}, []);
console.log('result:\n', result);

В общем и целом на втором этапе мы проверяем все собранные ключи (3 шт.) на соответствие и создаём новый массив с результатами этого обхода (4 шт.).

P.S. не знаю что за ерунда творится с "песочницей" на втором этапе, но код прекрасно работает. Можете проверить в консоли браузера.

→ Ссылка