Как отфильтровать массив по различным условиям, используя ES2016? - PullRequest
0 голосов
/ 29 ноября 2018

В приведенном ниже фрагменте нам нужно отфильтровать массив на основе различных условий И, ИЛИ.Условия

  1. Должен фильтроваться, если объект фильтра имеет значение "isFiltered" true.
  2. PatternGroupCode "OTHER" означает, что он включает все ткани, кроме тех тканей, которые помечены как "isFiltered" false.
  3. То же условие "OTHER" применяется к fabricColor.

IЯ могу фильтровать, используя идентификатор FabricColor.но не в состоянии сделать с помощью patternGroupCode.

// all products
let products = [
  { name: "A", fabricColorGroupCodes:["OTHER"], patternGroupCode: 'PLAID', size: 50 },
  { name: "B", fabricColorGroupCodes:["BLUE"], patternGroupCode: 'WINDOWPANE', size: 60 },
  { name: "C", fabricColorGroupCodes:["OTHER", "BLUE"], patternGroupCode: 'SOLID', size: 100 },
  { name: "D", fabricColorGroupCodes:["OTHER", "BLACK"], patternGroupCode: 'PLAID', size: 70 },
  { name: "E", fabricColorGroupCodes:["BLACK"], patternGroupCode: 'WINDOWPANE', size: 80 },
  { name: "F", fabricColorGroupCodes:["BLACK"], patternGroupCode: 'SOLID', size: 100 },
  { name: "G", fabricColorGroupCodes:["GREEN"], patternGroupCode: 'PLAID', size: 90 },
  { name: "H", fabricColorGroupCodes:["GREEN"], patternGroupCode: 'SOLID', size: 100 },
  { name: "I", fabricColorGroupCodes:["GREEN"], patternGroupCode: 'WINDOWPANE', size: 80 },
 { name: "J", fabricColorGroupCodes:["GREEN"], patternGroupCode: 'PAISLEY', size: 80 }
];

function multiFilter(array, filters) {
  return array.filter(d => ( 
    Object.entries(filters).every(([k ,v]) => (
      Object.values(v).map(m => m.id).includes(d[k].id) 
    )) 
  ));
}

// filter conditions
// here we choose OTHER so it will filter on color BLACK and GREEN and 
// omit the BLUE because isFilter tag is false, same for patternGroupCode.
// so here it filter on SOLID , PLAID and WINDOWPANE and will omit PAISLEY .
let filters = {
  fabricColor: [
    {"id": 'BLACK', "isFiltered": true}, 
    {"id": 'BLUE', "isFiltered": false},
    {"id": 'OTHER', "isFiltered": true}
  ], 
  patternGroupCode: [
    {"patternGroupCode": 'OTHER', "isFiltered": true}, 
    {"patternGroupCode": 'STRIPES', "isFiltered": false}, 
    {"patternGroupCode": 'PLAID', "isFiltered": true}, 
    {"patternGroupCode": 'PAISLEY', "isFiltered": false}, 
    {"patternGroupCode": 'SOLID', "isFiltered": true}
  ]
};

var filtered = multiFilter(products, filters);
console.log(filtered);

Ответы [ 3 ]

0 голосов
/ 29 ноября 2018

Я предлагаю упростить структуру данных, чтобы использовать более упрощенный фильтр и упрощенный объект фильтров.

function multiFilter(array, filters) {
    return array.filter(o =>
        Object
            .entries(filters)
            .every(([k, v]) => o[k] in v ? v[o[k]] : v.OTHER)
    );
}

var products = [
        { name: "A", fabricColor: 'BLUE', patternGroupCode: 'PLAID', size: 50 },
        { name: "B", fabricColor: 'BLUE', patternGroupCode: 'WINDOWPANE', size: 60 },
        { name: "C", fabricColor: 'BLUE', patternGroupCode: 'SOLID', size: 100 },
        { name: "D", fabricColor: 'BLACK', patternGroupCode: 'PLAID', size: 70 },
        { name: "E", fabricColor: 'BLACK', patternGroupCode: 'WINDOWPANE', size: 80 },
        { name: "F", fabricColor: 'BLACK', patternGroupCode: 'SOLID', size: 100 },
        { name: "G", fabricColor: 'GREEN', patternGroupCode: 'PLAID', size: 90 },
        { name: "H", fabricColor: 'GREEN', patternGroupCode: 'SOLID', size: 100 },
        { name: "I", fabricColor: 'GREEN', patternGroupCode: 'WINDOWPANE', size: 80 },
        { name: "I", fabricColor: 'GREEN', patternGroupCode: 'PAISLEY', size: 80 }
    ],
    filters = {
        fabricColor: { BLACK: true, BLUE: false, OTHER: true },
        patternGroupCode: { PLAID: true, SOLID: true, STRIPES: false, PAISLEY: false, OTHER: true }
    },
    filtered = multiFilter(products, filters);

console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 29 ноября 2018

Предположим, что мы будем фильтровать продукты, например, по размеру .


Структура

let products = [
  { name: "A", fabricColor: {"id": 'BLUE'}, patternGroupCode: 'PLAID', size: 50 },
  { name: "B", fabricColor: {"id": 'BLUE'}, patternGroupCode: 'WINDOWPANE', size: 60 },
  { name: "C", fabricColor: {"id": 'BLUE'}, patternGroupCode: 'SOLID', size: 100 },
  { name: "D", fabricColor: {"id": 'BLACK'}, patternGroupCode: 'PLAID', size: 70 },
  { name: "E", fabricColor: {"id": 'BLACK'}, patternGroupCode: 'WINDOWPANE', size: 80 },
  { name: "F", fabricColor: {"id": 'BLACK'}, patternGroupCode: 'SOLID', size: 100 },
  { name: "G", fabricColor: {"id": 'GREEN'}, patternGroupCode: 'PLAID', size: 90 },
  { name: "H", fabricColor: {"id": 'GREEN'}, patternGroupCode: 'SOLID', size: 100 },
  { name: "I", fabricColor: {"id": 'GREEN'}, patternGroupCode: 'WINDOWPANE', size: 80 },
 { name: "J", fabricColor: {"id": 'GREEN'}, patternGroupCode: 'PAISLEY', size: 80 }
];

Функциональность

const sizeAbove = value => o => o.size > value
const sizeBelow = value => o => o.size < value

products.filter(sizeAbove(90))
products.filter(sizeBelow(60))
0 голосов
/ 29 ноября 2018

Вы можете фильтровать продукты итерациями для каждого фильтра с помощью reduce (начиная с всего массива продуктов в качестве начального аккумулятора и возвращая отфильтрованную версию после применения каждого фильтра).

Кроме того, поскольку вы были открыты для изменения структуры ваших объектов, я сделал несколько небольших изменений (убрав id из ключа fabricColor в продуктах и ​​добавив его в patternGroupCodeфильтр объекта) просто чтобы быть последовательным.

function multiFilter(array, filters) {
  return Object.entries(filters).reduce((acc, [k, kFilters]) => {
    let isFiltered = new Set(kFilters.filter(f => f.isFiltered).map(f => f.id)),
      other = kFilters.some(f => f.id === 'OTHER' && f.isFiltered),
      notFiltered = new Set(kFilters.filter(f => !f.isFiltered).map(f => f.id));
    return acc.filter(p => other ? !notFiltered.has(p[k]) : isFiltered.has(p[k]));
  }, array);
}


let products = [{
    name: "A",
    fabricColor: 'BLUE',
    patternGroupCode: 'PLAID',
    size: 50
  },
  {
    name: "B",
    fabricColor: 'BLUE',
    patternGroupCode: 'WINDOWPANE',
    size: 60
  },
  {
    name: "C",
    fabricColor: 'BLUE',
    patternGroupCode: 'SOLID',
    size: 100
  },
  {
    name: "D",
    fabricColor: 'BLACK',
    patternGroupCode: 'PLAID',
    size: 70
  },
  {
    name: "E",
    fabricColor: 'BLACK',
    patternGroupCode: 'WINDOWPANE',
    size: 80
  },
  {
    name: "F",
    fabricColor: 'BLACK',
    patternGroupCode: 'SOLID',
    size: 100
  },
  {
    name: "G",
    fabricColor: 'GREEN',
    patternGroupCode: 'PLAID',
    size: 90
  },
  {
    name: "H",
    fabricColor: 'GREEN',
    patternGroupCode: 'SOLID',
    size: 100
  },
  {
    name: "I",
    fabricColor: 'GREEN',
    patternGroupCode: 'WINDOWPANE',
    size: 80
  },
  {
    name: "I",
    fabricColor: 'GREEN',
    patternGroupCode: 'PAISLEY',
    size: 80
  }
];

let filters = {
  fabricColor: [{
    "id": 'BLACK',
    "isFiltered": true
  }, {
    "id": 'BLUE',
    "isFiltered": false
  }, {
    "id": 'OTHER',
    "isFiltered": true
  }],
  patternGroupCode: [{
      "id": 'OTHER',
      "isFiltered": true
    },
    {
      "id": 'STRIPES',
      "isFiltered": false
    },
    {
      "id": 'PLAID',
      "isFiltered": true
    },
    {
      "id": 'PAISLEY',
      "isFiltered": false
    },
    {
      "id": 'SOLID',
      "isFiltered": true
    }
  ]
};

var filtered = multiFilter(products, filters);
console.log(filtered);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...