【问题标题】:Filter list based on more than one field基于多个字段的过滤列表
【发布时间】:2021-10-14 20:49:58
【问题描述】:

我正在迭代一个工作列表,并且在这个列表上实现了一个搜索。 搜索正常,但现在它只根据一个字段过滤列表。

这是我的清单:

<ion-card *ngFor="let job of allJobs | search : searchTerm">
    <ion-grid>
    <ion-row>
        <ion-col>
        <div>
            <span> {{job.day | uppercase}}</span>
            <span> {{job.month | uppercase}}</span>
        </div>
        </ion-col>

        <ion-col>
        <div>
            <span>{{job.time}}</span>
            <span>{{job.name}}</span>
        </div>
        </ion-col>
    </ion-row>
    </ion-grid>
</ion-card>

我为实现搜索做了一个管道。这是它的代码。

  transform(items: any[], terms: string): any[] {
    if(!items) return [];
    if(!terms) return items;
    terms = terms.toLowerCase();
    return items.filter( it => {
      return it.name.toLowerCase().includes(terms); // only filter name
    });
  }

现在列表仅根据name 字段进行过滤。我也想根据daymonthtime 过滤列表。

谁能告诉我如何做到这一点?

作业的样本数据。 Jobs 是一个对象数组

   [  
      {  
         "id":10,
         "day":"Monday",
         "month":"June",
         "time":"10",
         "name":"John",
         "email":"john@gmail.com"
      },
      {  
         "id":11,
         "day":"Tuesday",
         "month":"May",
         "time":"12",
         "name":"Jane",
         "email":"jane@gmail.com"
      },
      {  
         "id":12,
         "day":"Friday",
         "month":"June",
         "time":"16",
         "name":"",
         "email":"john@gmail.com"
      },
      {  
         "id":13,
         "day":"Tuesday",
         "month":"August",
         "time":"21",
         "name":"",
         "email":"kevin@gmail.com"
      },
      {  
         "id":14,
         "day":"Saturday",
         "month":"December",
         "time":"12",
         "name":"Sam",
         "email":"sam@gmail.com"
      },

   ]

searchTerm 只是一个字符串。

如您所见,示例数据中的字段比 HTML 中显示的字段多,但我只尝试搜索 HTML 中显示的字段。某些字段可以有空值(例如,示例数据中的name 有两个空值)

我尝试了已经提供的解决方案,但没有一个能满足我的要求。

P.S:在某处读到管道不是执行此类功能的最佳选择。我也准备在课堂上实现这个逻辑。

【问题讨论】:

    标签: ionic-framework ionic2 ionic3


    【解决方案1】:

    尝试将您的includeslogical or-operator (||) 结合起来:

    transform(items: any[], terms: string): any[] {
        if (!items) return [];
        if (!terms) return items;
        terms = terms.toLowerCase();
        return items.filter(it => {
          return it.name.toLowerCase().includes(terms) ||
            it.day.toLowerCase().includes(terms) ||
            it.month.toLowerCase().includes(terms) ||
            it.time.toLowerCase().includes(terms)
        });
    }
    

    如果includes 中的任何一个返回true,则此语句将返回true。所以基本上任何namedaymonthtime 包含搜索项的项目都将由管道返回。

    此解决方案假定 namedaymonthtime 不为 null 或未定义。但我假设这没关系,因为您的示例数据表明空值将是空字符串("")。如果我的假设不正确,您必须在访问它们之前检查这些值是否已分配。

    【讨论】:

      【解决方案2】:

      试试这个代码..它很简单。

        transform(items: any[], terms: string): any[] {
          if (!items) return [];
          if (!terms) return items;
          terms = terms.toLowerCase();
          terms = terms.trim();
          return items.filter(it => {
            if (it.day) {
              return it.day.toLowerCase().includes(terms);
            }
            if (it.month) {
              return it.month.toLowerCase().includes(terms);
            }
            if (it.time) {
              return it.time.toLowerCase().includes(terms);
            }
            if (it.name) {
              return it.name.toLowerCase().includes(terms);
            }
          });
        }
      

      如果您的 JSON 包含空值,您可以使用以下代码将其替换为空字符串:

      items = JSON.parse(JSON.stringify(items).replace(/null/g, '""'));
      

      【讨论】:

        【解决方案3】:

        这不起作用,因为includes 不测试多个术语案例。你没有说 items Array 里面的内容,但如果它是一个字符串,你可以这样做:

        transform(items: any[], terms: string): any[] {
            if(!items) return [];
            if(!terms) return items;
            terms = terms.toLowerCase();
            return items.filter( it => {
              //if it is something like "Programmer 07 November 12:00PM"
              var informations = it.split(' '); //["Programmer", "07" ,"November" ,"12:00PM"]
              var termArray = terms.split(' ');
              var rightResult = true;
              for (var index in termArray) {
               if !(informations.include(termArray[index])) {
                 rightResult = false;
               }
               return rightResult;
        
        
            });
          }
        

        【讨论】:

        • 试过你的代码。它不工作。我已经用示例数据更新了代码
        【解决方案4】:

        在搜索管道的转换方法中,对要应用过滤器的所有字段应用过滤器。以下将搜索对象中的所有键:

        transform(items: any[], terms: string): any[] {
            if(!items) return [];
            if(!terms) return items;
            terms = terms.toLowerCase();
            return items.filter( it => {
        
               return keys(it).reduce((prev, key) => {
                  return prev || key.toLowerCase().includes(term);
               }, false);
            });
        }
        

        如果键或 Object.keys 不起作用,请使用以下代码代替 reduce 函数:

        ...
        let bInclude = false;
        for(let key in it){
          bInclude = bInclude || key.toLowerCase().includes(term);
        }
        
        return bInclude;
        ...
        

        【讨论】:

        • 错误参考错误:未定义键@Shubham Chaudhary
        • 使用 Object.keys 代替。 @安娜贝尔
        • 试过了,但还是不行@Shubham Chaudhary
        • 编辑答案,使用 for..in 获取对象键作为数组
        • 试过你的代码。它仍然无法正常工作。我有示例数据并更新了问题。
        【解决方案5】:

        filterItems(param: any): void { 让 val: string = param;

        if (val) {
          if (val.trim() !== '') {
            this.filterItemsList = this.items.filter((data) => {
              console.log(data.category);
              return data.category.toLowerCase().indexOf(val.toLowerCase()) > -1
                || data.products.some(product => product.code.toLowerCase().indexOf(val.toLowerCase()) > -1);
            })
          }
        }
        

        }

        效果很好

        【讨论】:

        • this.searcgResinput = res; this.searcgDatainput = this.searcgResinput.data; this.searcgDatainput = this.searcgDatainput.filter((user) => { //console.log("check",user.customer_name); return (user.customer_name.toLowerCase().indexOf(this.input.toLowerCase() ) > -1 || user.dsr_no.toLowerCase().indexOf(this.input.toLowerCase()) > -1); }) 使用 ||管道你必须搜索多个字段
        猜你喜欢
        • 2021-12-14
        • 2016-09-17
        • 2023-03-18
        • 1970-01-01
        • 2021-01-12
        • 2021-11-28
        • 2020-12-27
        • 1970-01-01
        • 2021-03-11
        相关资源
        最近更新 更多