Фильтровать массив объектов на основе нескольких значений из другого массива объектов - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть массив объектов,

c = [
  {
     name: 'abc',
     category: 'cat1',
     profitc: 'profit1',
     costc: 'cost1'
  },
  {
     name: 'xyz',
     category: '',
     profitc: 'profit1',
     costc: ''
  },
  {
     name: 'pqr',
     category: 'cat1',
     profitc: 'profit1',
     costc: ''
  }
]

Теперь я хочу отфильтровать массив на основе другого массива объектов, второй массив объектов:

arr = [
 {
   type:'profitc'
   value: 'profit1',
 },
 {
   type:'category'
   value: 'cat1',
 }
]

Теперь arr отображается в раскрывающемся списке с возможностью множественного выбора, а значение ключевого значения в объекте отображается пользователю, т.е. profit1, cat1, et c. Поэтому, если пользователь выбирает profit1 и cat1, тогда мне нужно отфильтровать массив c так, чтобы вывод выглядел следующим образом.

c = [
  {
     name: 'abc',
     category: 'cat1',
     profitc: 'profit1',
     costc: 'cost1'
  },
  {
     name: 'pqr',
     category: 'cat1',
     profitc: 'profit1',
     costc: ''
  }
]

Я попытался сделать это.

let result = c.filter(e => {
  let istruecat = true

//arr is chosen value from user.
  arr.forEach(element => {
    istruecat = e[element.type] == element.value;
  })
  return istruecat;
})

Но когда я делаю это, я получаю все объекты из массива c. Что я здесь не так делаю? Есть ли способ сделать это с помощью loda sh.

Ответы [ 4 ]

1 голос
/ 25 апреля 2020

Вы можете отфильтровать массив, проверив все заданные пары ключ / значение с объектами данных.

var data = [{ name: 'abc', category: 'cat1', profitc: 'profit1', costc: 'cost1' }, { name: 'xyz', category: '', profitc: 'profit1', costc: '' }, { name: 'pqr', category: 'cat1', profitc: 'profit1', costc: '' }],
    filters = [{ type: 'profitc', value: 'profit1', }, { type: 'category', value: 'cat1' }],
    result = data.filter(o => filters.every(({ type, value }) => o[type] === value));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 25 апреля 2020

-Вы вычисляете istruecat, основываясь только на последней записи в arr. Вы должны использовать вместо этого уменьшить, чтобы накопить значение:

let result = c.filter(e => arr.reduce((acc, element) => acc && e[element.type] === element.value, true))
0 голосов
/ 25 апреля 2020

Или рекурсивное и не читаемое решение:

function myFilter(c, [first, ...rest]) {
    if (first) {
        const {type, value} = first;
        // Recursively call myFilter with one filter removed
        return myFilter(c, rest)
           .filter(x => x[type] === value);
    } else {
        // Nothing left to filter
        return c;
    }
}

myFilter(c, arr);
0 голосов
/ 25 апреля 2020

Вот реализация сокращения списка c на основе заданных значений массивом фильтров arr. Обратите внимание, что вывод представляет собой новый список на основе исходного содержимого в c.

result = arr.reduce((acc, curr) => {
    acc = acc.filter(item => {
        return item[curr.type] === curr.value;
    });

    return acc;
}, c);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...