首页 > 解决方案 > 如何通过搜索词减少对象数组

问题描述

我有一个产品数组,如果产品标题或产品标签列表包含搜索词,我希望创建一个新数组。

下面是简化版。

const products = [{title: 'apple-green', tags: [{colour: 'red', tagType: 'colour'}]},
                      {title: 'orange', tags: [{colour: 'orange', tagType: 'colour'}]},
                      {title: 'cherry', tags: [{colour: 'red', tagType: 'colour'}]},
                      {title: 'pear', tags: [{colour: 'green', tagType: 'colour'}]}]

const searchTerm = "green"

const result = [{title: 'apple-green', tags: [{colour: 'red', tagType: 'colour'},
                {title: 'pear', tags: [{colour: 'green', tagType: 'colour'}]}]

我认为使用 reduce 将是实现这一目标的最佳方法。

我尝试了以下但没有成功。

const result = products.reduce((acc, product) => {
  if (product.title.toLowerCase().includes(searchTerm.toLowerCase()) || 
      product.tags.map((tag) => 
        tag.title.toLowerCase().includes(searchTerm.toLowerCase()))) 
    return product

  return [acc, ...product]
}, [])

任何帮助都会受到极大的欢迎。

标签: javascriptecmascript-6

解决方案


Array#filter可能是这个而不是 的正确函数Array#reduce,因为似乎没有对输出结构应用任何转换(即使是这样,map/filter可能比 更清晰reduce)。

在编写了一个辅助函数来执行不区分大小写的子字符串/包含检查后,您可以使用Array#someonproduct.tags来确定tag.colour产品标签数组中的任何属性是否与搜索词匹配。

const products = [{title: 'apple-green', tags: [{colour: 'red', tagType: 'colour'}]}, {title: 'orange', tags: [{colour: 'orange', tagType: 'colour'}]}, {title: 'cherry', tags: [{colour: 'red', tagType: 'colour'}]}, {title: 'pear', tags: [{colour: 'green', tagType: 'colour'}]}];

const includesAnyCase = (s, t) => s.toLowerCase().includes(t.toLowerCase());

const filterProducts = (products, searchTerm) =>
  products.filter(product =>
    includesAnyCase(product.title, searchTerm) || 
    product.tags.some(tag => includesAnyCase(tag.colour, searchTerm))
  )
;

console.log(filterProducts(products, "green"));


推荐阅读