es6 фильтрует массив объектов по массиву объектов фильтра - PullRequest
0 голосов
/ 11 декабря 2018

с учетом следующей структуры:

let filteredTasks = [
  {status: 'done', other: true},
  {status: 'nope', other: false},
  {status: 'done', other: true},
  {status: 'done', other: true},
  {status: 'done', other: false},
  {status: 'done', other: false},
  {status: 'started', other: false}
]

и:

let availableFilters = [{status: 'done'}, {other: false}]

как мне отфильтровать этот массив, чтобы получить следующие результаты:

filteredTasks =
[{status: 'done', other: false}, {status: 'done', other: false}]

myмысли и попытки:

let filteredTasks = [
  {status: 'done', other: true},
  {status: 'nope', other: false},
  {status: 'done', other: true},
  {status: 'done', other: true},
  {status: 'done', other: false},
  {status: 'done', other: false},
  {status: 'started', other: false}
]

let availableFilters = [{status: 'done'}, {other: false}]

let filteredTasksList = availableFilters.map(item => {
    return runFilter(item)
})

function runFilter(currentFilter) {
  return filteredTasks.filter(item => {
    for (var key in currentFilter) {
        if (item[key] === undefined || item[key] !== currentFilter[key])
        return false
    }
    return true;
  })
}

... но, очевидно, это имеет преимущественную силу при каждом проходе.

Как всегда, любая обратная связь и помощь очень приветствуются, поэтому спасибо заранее.

РЕДАКТИРОВАТЬ: принял первоначальный комментарий в качестве решения, поскольку оно соответствует моим потребностям.Я использовал это, чтобы сделать шаг вперед:

let filterTaskList = (list, filters) => {
  let entries = Object.entries(Object.assign(...filters))
  return list.filter(task => {
    return entries.every(([key, val]) => {
      return task[key] === val
     })
  })
}

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Сначала код:

let filteredTasks = [
  {status: 'done', other: true},
  {status: 'nope', other: false},
  {status: 'done', other: true},
  {status: 'done', other: true},
  {status: 'done', other: false},
  {status: 'done', other: false},
  {status: 'started', other: false}
]

let availableFilters = [{status: 'done'}, {other: false}]

const matchesFilter = (filter, item) => Object.entries(filter).every(([key, value]) => item[key] === value)

function withFilters (filters) {
  return item => filters.every(f => matchesFilter(f, item))
}

console.log(filteredTasks.filter(withFilters(availableFilters)))

Объяснение: две интересные функции здесь matchesFilter и withFilters.

matchesFilter: берет объект, filter и сравнивает каждый ключ / значение с item, чтобы убедиться, что он совпадает.

withFilters принимает список фильтров ивозвращает функцию, которую можно использовать с Array.prototype.filter для создания отфильтрованного списка.

Затем вы просто используете withFilters(availableFilters) в качестве функции фильтра.Вы даже можете сохранить этот результат, чтобы использовать его позже.

let filterByAvailable = withFilters(availableFilters)
let availableTaks = filteredTasks.filter(filterByAvailable)
0 голосов
/ 11 декабря 2018

Вы можете создать один объект из фильтров и принять записи для фильтрации.

let filteredTasks = [
  {status: 'done', other: true},
  {status: 'nope', other: false},
  {status: 'done', other: true},
  {status: 'done', other: true},
  {status: 'done', other: false},
  {status: 'done', other: false},
  {status: 'started', other: false}
],
 availableFilters = [{status: 'done'}, {other: false}], // your filters
  filters = Object.entries(Object.assign(...availableFilters)), // returns an array of the filter's own enumerable property
  result = filteredTasks.filter(o => filters.every(([k, v]) => o[k] === v)); // .every returns true, when every item is fulfilling the condition
  
console.log(result);
  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...