【问题标题】:Filtering nested objects and arrays过滤嵌套对象和数组
【发布时间】:2022-12-03 11:59:53
【问题描述】:

我有一个 Vue 项目,需要在包含嵌套对象的数组中搜索特定对象,然后返回它。用户有一个用于搜索的文本输入字段,搜索应该以“title”为目标。

数据如下所示:

const data = 
[{
    "catId": "1",
    "catTitle": "a",
    "exampleArray": [{
        "id": "111",
        "title": "aaa"
    }, {
        "id": "222",
        "title": "bbb"
    }, {
        "id": "333",
        "title": "ccc"
    }]
}, {
    "catId": "2",
    "catTitle": "b",
    "exampleArray": [{
        "id": "444",
        "title": "ddd"
    }, {
        "id": "555",
        "title": "eee"
    }]
}, {
    "catId": "3",
    "catTitle": "c",
    "exampleArray": []
}, {
    "catId": "4",
    "catTitle": "d",
    "exampleArray": [{
        "id": "555",
        "title": "fff"
    }]
}]

我努力了:


return data.filter(item => {
                    return item.catArray.filter(category=> {
                        return category.title.toLowerCase().includes(this.search.toLowerCase())
                    })
                })

例如如果用户输入是“aaa”,应该返回:


[{
    "catId": "1",
    "catTitle": "a",
    "exampleArray": [{
        "id": "111",
        "title": "aaa"
    }]
}]

搜索还应返回所有匹配结果。

【问题讨论】:

    标签: javascript arrays vue.js


    【解决方案1】:

    你快到了!

    const data = 
    [{
        "catId": "1",
        "catTitle": "a",
        "exampleArray": [{
            "id": "111",
            "title": "aaa"
        }, {
            "id": "222",
            "title": "bbb"
        }, {
            "id": "333",
            "title": "ccc"
        }]
    }, {
        "catId": "2",
        "catTitle": "b",
        "exampleArray": [{
            "id": "444",
            "title": "ddd"
        }, {
            "id": "555",
            "title": "eee"
        }]
    }, {
        "catId": "3",
        "catTitle": "c",
        "exampleArray": []
    }, {
        "catId": "4",
        "catTitle": "d",
        "exampleArray": [{
            "id": "555",
            "title": "fff"
        }]
    }];
    const search = "fff";
    
    console.log(data.filter(item => {
                        return item.exampleArray.some(category=> {
                            return category.title.toLowerCase().includes(search.toLowerCase())
                        })
                    }))

    我所做的只是在过滤器之后添加一个长度检查。因为 filter 期望 true 或 false 来知道是否应该包含该元素。虽然它返回一个包含结果的数组,但空数组是一个真值。您需要检查数组是否包含要正确过滤的元素。

    编辑:我改为使用 FIND 而不是 FILTER。如果未找到任何内容,Find 将返回假值,而如果找到某些内容,则返回真值(找到的元素)。这样做的好处是不会遍历整个数组,只要我们找到一些东西就停止。

    再次编辑:some 是你想要的功能,我们每天都在学习!它与 find 的作用相同,但直接返回 true!

    【讨论】:

    • 在旁注中,您可以使用 find 而不是 filter/some ,考虑一下我认为这将是最好的。
    • 我建议使用 some 而不是嵌套的 filter(...).length > 0。它具有相同的效果,但更简洁高效
    • 哦,你是对的......刚刚读到它,从未真正使用过它我真的认为它是过滤器的别名!谢谢
    【解决方案2】:

    要在对象数组中搜索特定对象并将其返回,可以使用 Array.prototype.find() 方法。 find() 方法接受一个回调函数,该函数返回一个布尔值,指示该对象是否应包含在结果中。

    下面是一个示例,说明如何使用 find() 方法在数据数组中搜索特定对象并将其返回:

    const data = [
      {
        catId: "1",
        catTitle: "a",
        exampleArray: [
          {
            id: "111",
            title: "aaa",
          },
          {
            id: "222",
            title: "bbb",
          },
          {
            id: "333",
            title: "ccc",
          },
        ],
      },
      // ...
    ];
    
    // The search term that the user entered
    const searchTerm = "aaa";
    
    // Use the find() method to search the data array for the object that has
    // a title property that includes the search term
    const result = data.find((item) => {
      return item.exampleArray.some((item) => {
        return item.title.toLowerCase().includes(searchTerm.toLowerCase());
      });
    });
    console.log(result);
    // The result will be:
    // {
    //   "catId": "1",
    //   "catTitle": "a",
    //   "exampleArray": [{
    //     "id": "111",
    //     "title": "aaa"
    //   }]
    // }

    在此代码中,find() 方法用于在数据数组中搜索具有包含搜索项的 title 属性的对象(在与 title 属性进行比较之前将其转换为小写以使搜索不区分大小写) .

    Array.prototype.some() 方法在传递给 find() 的回调函数中使用,以检查 exampleArray 属性中的任何对象是否具有包含搜索词的 title 属性。

    如果在其中一个标题属性中找到搜索词,则 find() 方法将返回包含它的对象。否则,它将返回未定义。

    【讨论】:

      【解决方案3】:

      这是您可以完成此操作的一种方法:

      return data.Filter(item => {
        // filter the `exampleArray` for each `item` by checking if the `title` property of each object in the array contains the search string
        const matchingItems = item.exampleArray.filter(example => example.title.toLowerCase().includes(this.search.toLowerCase()));
        // return `true` for the current `item` if there are any matching items in the `exampleArray`
        return matchingItems.length > 0;
      });
      

      此代码将过滤数据数组以仅包含 exampleArray 中至少有一个对象具有包含搜索字符串的标题属性的对象。它还将为每个项目仅返回 exampleArray 中的匹配对象。

      如果搜索字符串是“aaa”,这将返回以下数组:

      [
         {
            "catId":"1",
            "catTitle":"a",
            "exampleArray":[
               {
                  "id":"111",
                  "title":"aaa"
               }
            ]
         }
      ]
      

      【讨论】:

        【解决方案4】:

        您可以借助 Array.filter() 方法以及 String.includes() 来实现此要求

        现场演示:

        const data = [{
          "catId": "1",
          "catTitle": "a",
          "exampleArray": [{
            "id": "111",
            "title": "aaa"
          }, {
            "id": "222",
            "title": "bbb"
          }, {
            "id": "333",
            "title": "ccc"
          }]
        }, {
          "catId": "2",
          "catTitle": "b",
          "exampleArray": [{
            "id": "444",
            "title": "ddd"
          }, {
            "id": "555",
            "title": "eee"
          }]
        }, {
          "catId": "3",
          "catTitle": "c",
          "exampleArray": []
        }, {
          "catId": "4",
          "catTitle": "d",
          "exampleArray": [{
            "id": "555",
            "title": "fff"
          }]
        }];
        
        const searchWord = 'aaa';
        
        const res = data.filter(obj => {
          obj.exampleArray = obj.exampleArray.filter(({ title }) => title.includes(searchWord))
          return obj.exampleArray.length;
        });
        
        console.log(res);

        【讨论】:

          猜你喜欢
          • 2019-10-15
          • 1970-01-01
          • 2020-03-11
          • 2020-07-18
          • 2021-08-01
          • 2020-03-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多