如何使用ES2016在不同条件下过滤数组



在下面的代码段中,我们需要根据不同的AND、OR条件筛选数组。条件

  1. 如果筛选对象的"isFiltered"为true,则应该进行筛选
  2. PatternGroupCode"OTHER"表示它包括除以下织物之外的所有织物标记为"isFiltered"false的结构
  3. fabricColor也适用相同的"OTHER"条件

我可以使用fabricColor id进行过滤,但不能使用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);

您可以使用reduce在每个过滤器的迭代中过滤产品(从整个产品数组开始作为初始累加器,并在应用每个过滤器后返回过滤版本(。

此外,由于您对修改对象的结构持开放态度,为了保持一致,我继续进行了一些小的更改(从产品中的fabricColor键中删除id,并将其添加到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);

我建议简化数据结构,使用更简化的过滤器和简化的过滤器对象。

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; }

假设我们将过滤产品,例如通过大小


结构

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

最新更新