【问题标题】:How do I filter a javascript object when making a search pipe with angular 2?使用角度 2 创建搜索管道时如何过滤 javascript 对象?
【发布时间】:2016-08-05 10:12:53
【问题描述】:

我正在尝试为 Angular 2 创建一个搜索管道。 它应该采用嵌套对象并过滤掉与搜索词匹配的对象。 我有一个基本版本,但我遇到了两个问题。

问题之一是,我现在必须对键名进行硬编码,或者使用在我看来像 JSON.stringify 的肮脏黑客。

有什么更优雅的过滤对象的方法,将术语与除_idurl 等硬编码列表之外的任何值匹配?

问题二是,如果字符串term 包含一个空格,我想拆分它并用这两个术语过滤obj。 我可以使用terms = term.split(' '); 拆分它。

但是如何实现多个词的过滤?

我当前的代码:

import {Pipe} from 'angular2/core';

@Pipe({
    name: "search"
})
export class SearchPipe{
    transform(obj: any, [term]) {
        if (obj != null && term) {
            return obj.filter( el => {

                //var test = JSON.stringify(el); 
                //return test.toLowerCase().includes(term.toLowerCase()); //trows a compile error but seems to work.

                return el.name.toLowerCase().includes(term.toLowerCase()) || el.place.toLowerCase().includes(term.toLowerCase()) || el.title.toLowerCase().includes(term.toLowerCase()) ;

            });

        } else {
            return obj;
        }
    }
}

预期的输入格式:

[
{
  "_id": "56ffbe512ba199777d51c6ae",
  "picture": "http://placehold.it/36x36",
  "name": "Melissa Reeves",
  "company": "Orbixtar",
  "place": "Greenwich, Belarus",
  "title": "voluptate est ipsum",
  "location": {
    "lat": -78.926961,
    "lng": 90.157653
  },
  "url": "http://lol.lol"
},
{
  "_id": "56ffbe5119cf66e94b3800b4",
  "picture": "http://placehold.it/36x36",
  "name": "Chelsea Lindsay",
  "company": "Squish",
  "place": "Vowinckel, Belarus",
  "title": "anim ea exercitation",
  "location": {
    "lat": 66.547582,
    "lng": 162.720388
  },
  "url": "http://lol.lol"
}
]

如果术语是"term1",我希望它返回包含“term1”的对象。

如果另一方面术语是"term1 term2 term3",我希望它返回包含所有术语但不一定按特定顺序的所有对象。

例如。

术语"Melissa" 应该返回第一个对象。

术语"Melissa Belarus" 也应该只返回第一个对象。 即使第二个对象匹配其中一个键。

【问题讨论】:

  • 首选(el) => { 而不是function (el) { 以使用类而不是函数保留this 的范围。
  • 您能否添加一个示例,具体的term 的结果应该是什么样子?
  • 感谢您指出这一点。很高兴知道。我为术语添加了一个示例。

标签: javascript filter typescript angular


【解决方案1】:

试试这个(未经测试)

@Pipe({
  name: "search"
})
export class SearchPipe{
  transform(obj: any, [term]) {
    if (obj != null && term) {
      return obj.filter( el => {

        var test = JSON.parse(JSON.stringify(el));
        delete test['url'];
        delete test['_id'];

        var testString = JSON.stringify(test);

        Object.keys(test).forEach(k => {
          testString = testString.replace(k, '');
        });

        let terms = term.replace(/[\s]+/gm, " ").replace(/^[\s]|[\s]$/gm, "").split(' ');
        let containCount = 0;

        terms.forEach(t => {
          if(testString.toLowerCase().indexOf(t.toLowerCase()) > -1)
          {
            ++containCount;
          }
        });

        return (containCount == terms.length);
      });

    } else {
      return obj;
    }
  }
}

【讨论】:

  • 这适用于一个有一些编辑的术语。 indexOf 并不总是返回 true,因此必须测试!== -1,第二个问题是,在拆分字符串时,您会在空格所在的位置得到一个空值。就像["term1",,"term2"] 一样,我用let newArray = []; for (var i = 0; i < terms.length; i++) { if (terms[i]) { newArray.push(terms[i]); } } 解决了这个问题
  • 这个解决方案的严重问题是不匹配两个术语,它返回匹配任何术语的对象。这不是我想要的结果。感谢您抽出宝贵时间:)
  • 我的错...要清楚地了解您的要求,需要更多有关所需输入和输出的信息....没什么。
  • 我在我的问题中添加了一个例子。我希望这能说清楚。 :)
  • 不要介意包含空元素的数组的问题。一个简单的.trim() 解决了这个问题
猜你喜欢
  • 2021-01-27
  • 1970-01-01
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
  • 1970-01-01
  • 2019-01-18
相关资源
最近更新 更多