如何使用多个参数过滤数据?
我想在过滤器中使用多个值,并将它们与and
条件结合起来。
如您所见,假设我在PQR
中键入Organization
,在Mond
中键入Sales Person
,这意味着我只希望Organization
是{ {1}}和PQR
是Sales Person
。
即合并这些条件,但是我遇到的问题是,如果我在其他输入Mond
为空的情况下合并这些条件,则不会返回任何数据。
我的代码在(filters)
条件(其中任何条件都匹配)的情况下都能正常工作。如何通过结合以上查询来实现相同类型的输出
这是我的代码文件,OR
是我正在尝试的功能
executeFilters()
答案 0 :(得分:2)
您已经说过要使用AND条件,但是当您这样做并且并非所有过滤器都具有值时,所有内容都会被过滤掉。我假设您使用的是&&
版的函数(问题上您仍然有||
)。
在应用过滤器之前,您需要检查过滤器是否具有值:
const filteredReport = this.reports.filter(report =>
(!this.organizationFilter || report.organization === this.organizationFilter) &&
(!this.customerFilter || report.customer === this.customerFilter) &&
(!this.salesPersonFilter || report.salesPerson === this.salesPersonFilter) &&
(!this.itemFilter || report.item === this.itemFilter) &&
(!this.authorizingOfficerFilter || report.authorizingOfficer === this.authorizingOfficerFilter) &&
(!this.itemFilter || report.item === this.itemFilter)
);
该列表中的每个标准都采用以下格式:
(!fieldFilterValue || report.field === fieldFilterValue)
...表示如果A)没有fieldFilterValue
(例如,虚假)或 B)存在,并且报告匹配,则报告将匹配
然后将它们全部与&&
连接在一起,因此整个过滤器为AND过滤器。
请注意,伪造的支票(!fieldFilterValue
)可能适合也可能不适用于您的所有字段,因此请在必要时进行调整。例如,如果您有一个数字字段,并且想要搜索该数字字段值为0
的报告,那么上面的代码将不起作用。在这种情况下,您可以在不使用该过滤器时将null
用作fieldFilterValue
的值,并将上面的代码调整为:
const filteredReport = this.reports.filter(report =>
(this.organizationFilter === null || report.organization === this.organizationFilter) &&
(this.customerFilter === null || report.customer === this.customerFilter) &&
(this.salesPersonFilter === null || report.salesPerson === this.salesPersonFilter) &&
(this.itemFilter === null || report.item === this.itemFilter) &&
(this.authorizingOfficerFilter === null || report.authorizingOfficer === this.authorizingOfficerFilter) &&
(this.itemFilter === null || report.item === this.itemFilter)
);
旁注:我很想避免通过使用filters
对象而不是单独的organizationFilter
,customerFilter
等属性来避免包含大量此类过滤器:
this.filters = {
organization: null,
customer: null,
salesPerson: null,
item: null,
authorizingOfficer: null,
item: null,
};
然后执行以下操作:
const filteredReport = this.reports.filter(report =>
Object.entries().every(([key, value]) => value === null || report[key] === value)
);
其缺点是您无法再搜索organizationFilter
并找到它的所有用法...
答案 1 :(得分:2)
您可以分阶段使用多个过滤器,从而可以实现更复杂的匹配逻辑,而不仅仅是===
:
const filteredReport = this.reports
.filter(report => {
if (!this.organizationFilter) return true // don't filter if blank
else return report.organization === this.organizationFilter
})
.filter(report => {
if (!this.customerFilter) return true
else return report.customer === this.customerFilter
})
.filter(report => {
if (!this.salesPerson) return true
else return report.salesPerson === this.salesPersonFilter
})
.filter(report => {
if (!this.itemFilter) return true
else return report.item === this.itemFilter
})
.filter(report => {
if (!this.authorizingOfficerFilter) return true
else return report.authorizingOfficer === this.authorizingOfficerFilter
});
如果您像我一样懒,甚至可以做一些元编程,然后循环执行:
let filteredReport = this.reports.slice();
[
'organization',
'customer',
'salesPerson',
'item',
'authorizingOfficer'
].forEach(attr => {
filteredReport = filteredReport.filter(report => {
if (!this[attr + 'Filter']) return true
else return report[attr] === this[attr + 'Filter']
});
});
尽管就我个人而言,我现在将重命名过滤器this.filters.customer
等以使过滤器代码更简洁:
if (!this.filters[attr]) return true
else return report[attr] === this.filters[attr]
答案 2 :(得分:1)
以下代码将解决您的问题。如果filter是一个对象而不是一组字符串,从一开始就会更好。首先,您需要在组件类之外创建一个接口:
interface Filter{
organization?: string,
customer?: string,
salesPerson?: string,
item?: string,
authorizingOfficer?: string
}
然后在您的组件网内:
filters: Filter;
executeFilters(): void {
let filteredReport = this.reports;
for(filterKey in this.filters){
filteredReport = filteredReport.filter(report => this.filters[filterKey] === report[filterKey]);
}
this.dataSource = new MatTableDataSource(filteredReport);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}