如何过滤具有多个参数的javsScript数组

时间:2020-01-11 15:04:28

标签: javascript angular

如何使用多个参数过滤数据? 我想在过滤器中使用多个值,并将它们与and条件结合起来。 如您所见,假设我在PQR中键入Organization,在Mond中键入Sales Person,这意味着我只希望Organization是{ {1}}和PQRSales Person

即合并这些条件,但是我遇到的问题是,如果我在其他输入Mond为空的情况下合并这些条件,则不会返回任何数据。 我的代码在(filters)条件(其中任何条件都匹配)的情况下都能正常工作。如何通过结合以上查询来实现相同类型的输出 这是我的代码文件,OR是我正在尝试的功能

executeFilters()

图片以便更好地理解 Picture for better understanding

3 个答案:

答案 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对象而不是单独的organizationFiltercustomerFilter等属性来避免包含大量此类过滤器:

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;

  }