如何基于配置对象创建筛选条件来筛选数组的数据项



我有一个进程,它根据复选框状态的变化动态地创建一种config对象,该对象描述了如何构建筛选数据项数组的条件。

筛选器配置可能看起来像这样。。。

const filter = {
publicationType: ['type-1', 'type-2'],
termType: ['term-1', 'term-2'],
reportFormat: ['xml'],
}

数据项的简化列表如下所示。。。

const data = [
{ id: 1, reportFormat: 'txt', termType: 'term-1', publicationType: 'type-1' },
{ id: 2, reportFormat: 'xml', termType: 'term-2', publicationType: 'type-2' },
{ id: 3, reportFormat: 'txt', termType: 'term-2', publicationType: 'type-2' },
]

我希望条件匹配每个类别/类型(配置的键(,但其值可以是类别/类型数组中的一个

根据提供的示例数据和规范,预期的过滤结果将是。。。

[{ id: 2, reportFormat: 'xml', termType: 'term-2', publicationType: 'type-2' }]

基于所提供的filter配置对象构建正确的过滤条件的方法看起来怎么样。

以下是我尝试创建一个筛选功能,但如果我尝试在多个Select组件上进行筛选,则筛选只能在单个Select组件上正常工作——数据重复。

const handleFilter = (val) => {
const filterKeys = Object.keys(val);
const filteredStats = [];
// loop objects in fetched arr
for (const item of stat) {
// loop properties by which filtering data
filterKeys.forEach((keys) => {
// check if data property match with a filtering property in array
const isPresent = val[keys].some((key) => {
const statProperty = item[keys];
const filterProperty = key;
return filterProperty === statProperty;
});
if (isPresent) {
filteredStats.push(item);
}
});
}
setfilteredState(filteredStats);
};

https://codesandbox.io/s/checkbox-filter-vqex7?file=/src/App.js

该方法的基本技术之一是利用几乎每个Array方法都允许额外传递target对象的事实,该解决方案将其用于例如Array.prototype.filterArray.prototype.every

主要方法是为数据数组的filter方法的每次迭代读取并应用过滤器配置。

此函数需要迭代配置的entriesevery键值(列表(对,以检查特定数据项是否与特定配置的条件项匹配。

后一个任务由另一个可以访问数据项的函数来完成;知道"两者,该数据项当前要检查属性键和可能有效的特性值列表,这使得检查最终条件的some是否适用变得容易。

仍然存在一个边缘情况,即空值列表,需要由后一个函数处理。由于其校验的真实性依赖于CCD_ 11。。。(对于空数组,some的默认返回值是false[].some(x => true) === false(。。。必须通过显式返回CCD_ 15作为其满足的前提条件CCD_。

function doesBoundItemMatchConditionEntry([key, valueList]) {
const item = this;
const itemValue = item[key];
return ((
valueList.length === 0
) || (
item.hasOwnProperty(key) &&
valueList.some(value => value === itemValue)
));
}
function doesItemMatchConditionsOfBoundConfig(item) {
// const config = this;
return Object
.entries(this)
.every(doesBoundItemMatchConditionEntry, item);
}
const filterConfig = {
publicationType: ['type-1', 'type-2'],
termType: ['term-1', 'term-2'],
reportFormat: ['xml'],
}
const sampleData = [
{ id: 1, reportFormat: 'txt', termType: 'term-1', publicationType: 'type-1' },
{ id: 2, reportFormat: 'xml', termType: 'term-2', publicationType: 'type-2' },
{ id: 3, reportFormat: 'txt', termType: 'term-2', publicationType: 'type-2' },
{ id: 4, reportFormat: 'txt', termType: 'term-2', publicationType: 'type-1' },
{ id: 5, reportFormat: 'xml', termType: 'term-1', publicationType: 'type-2' },
{ id: 6, reportFormat: 'txt', termType: 'term-1', publicationType: 'type-2' },
]
console.log(
'sampleData.filter(doesItemMatchConditionsOfBoundConfig, filterConfig) ...',
sampleData.filter(doesItemMatchConditionsOfBoundConfig, filterConfig)
);
console.log(
`sampleData.filter(doesItemMatchConditionsOfBoundConfig, {
publicationType: ['type-2'],
termType: ['term-1'],
reportFormat: [],
}) ...`,
sampleData.filter(doesItemMatchConditionsOfBoundConfig, {
publicationType: ['type-2'],
termType: ['term-1'],
reportFormat: [],
})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

相关内容

  • 没有找到相关文章

最新更新