如何搜索值和嵌套数组值

时间:2019-10-18 07:20:55

标签: typescript search ionic4

有一个具有不同值的产品对象数组。

products: object[] = [];

产品阵列中装有产品。有些带有标签,有些没有。

[
  { _id: 'xxx',
    name: 'ProductA',
    price: '1',
    tags: [ 'tag1', 'tag2' ]
  },
  { _id: 'yyy',
    name: 'ProductB',
    price: '5'
  }
]

必须通过 NAMEPRICETAGS

搜索产品

我们将Ionic 4中的ion-searchbar与ts文件中的以下代码一起使用

searchProducts(param: any): void {
  const val: string = param;
  this.resetProducts();

  if (val.trim() !== '') {
      this.products = this.products.filter(product => {
        return (
          product.name.toLowerCase().indexOf(val.toLowerCase()) > -1 ||
          product.price.toLowerCase().indexOf(val.toLowerCase()) > -1 ||
          product.tags.filter((tag: string) => {
            return tag.toLowerCase().indexOf(val.toLowerCase()) > -1
          });
        );
      });
  } else if (val.trim() === '') {
    this.resetProducts();
  }
}

每个搜索的结果是产品数组中的所有产品。

如果删除标签过滤器并仅搜索名称和价格,该功能将为我们提供正确的结果。

有人可以指向正确的方向来获取返回名称,价格和标签值的函数吗?

4 个答案:

答案 0 :(得分:1)

编辑

product.tags.filter((tag: string) => {
            return tag.toLowerCase().indexOf(val.toLowerCase()) > -1
});


product.tags.some((tag: string) => {
                if(!tag) return false;
                return tag.toLowerCase().indexOf(val.toLowerCase()) > -1
});

编辑:
使用some()方法代替filter()
filter()返回一个包含该数组所有元素的新数组,为此提供的过滤函数返回true。
如果该数组中的至少一个元素满足提供的测试功能,则如some()返回。

答案 1 :(得分:1)

一个简单的解决方法,只需添加products.tags &&

此外,将product.tags.filter更改为product.tags.some

这是因为如果没有任何标签匹配项,则filter将返回[],这在逻辑表达式中将强制转换为true

searchProducts(param: any): void {
  const val: string = param;
  this.resetProducts();

  if (val.trim() !== '') {
      this.products = this.products.filter(product => {
        return (
          product.name.toLowerCase().indexOf(val.toLowerCase()) > -1 ||
          product.price.toLowerCase().indexOf(val.toLowerCase()) > -1 ||
          product.tags && product.tags.some((tag: string) => {
            return tag.toLowerCase().indexOf(val.toLowerCase()) > -1
          });
        );
      });
  } else if (val.trim() === '') {
    this.resetProducts();
  }
}

上面的代码实际上可以转换为下面的代码,以减少噪声。

searchProducts(param: any): void {
  const val: string = param;
  this.resetProducts();

  if (val.trim() !== '') {
      this.products = this.products.filter(product => 
          [
            product.name,
            product.price,
            ...(product.tags || [])
          ].some(value => value.toLowerCase().includes(val.toLowerCase()))
      );
  } else if (val.trim() === '') {
    this.resetProducts();
  }
}

答案 2 :(得分:0)

[
  { _id: 'xxx',
    name: 'ProductA',
    price: '1',
    tags: [ 'tag1', 'tag2' ]
  },
  { _id: 'yyy',
    name: 'ProductB',
    price: '5'
  }
] 


Based on your method on searchProducts, you are filtering the tags key in the products array but product array doesn't have the `TAGS` key as per your sample above.

product.tags.filter((tag: string) => {
                return tag?tag.toLowerCase().indexOf(val.toLowerCase()) > -1:false;
});

答案 3 :(得分:0)

这里是@WongJiaHau发布的解决方案的简洁版本:

        Table AverageTable = HTable
           .filter("ID.isNotNull && dateTime.isNotNull && result.isNotNull && unixDateTime.isNotNull")
           .select("ID, dateTime, result, unixDateTime")
           .window(Tumble.over("100.rows").on("dateTime").as("movingAverage100"))
            .groupBy("movingAverage100")
           .select("avg(result) as avgResult");