繁体   English   中英

如何根据嵌套对象数组中的键过滤对象数组?

[英]How can I filter through an array of objects based on a key in a nested array of objects?

我很难根据嵌套对象数组中的值过滤对象数组。 我有一个聊天应用程序,其中一个组件呈现用户拥有的聊天列表。 当用户输入输入元素时,我希望能够按名称过滤聊天。

这是数组或初始 state 的示例:

const chats= [
  {
    id: "1",
    isGroupChat: true,
    users: [
      {
        id: "123",
        name: "Billy Bob",
        verified: false
      },
      {
        id: "456",
        name: "Superman",
        verified: true
      }
    ]
  },
  {
    id: "2",
    isGroupChat: true,
    users: [
      {
        id: "193",
        name: "Johhny Dang",
        verified: false
      },
      {
        id: "496",
        name: "Batman",
        verified: true
      }
    ]
  }
];

我希望能够按用户名称进行搜索,如果名称存在于其中一个对象(聊天)中,则返回整个 object。

这是我尝试过但没有结果的方法

 const handleSearch = (e) => {

    const filtered = chats.map((chat) =>
      chat.users.filter((user) => user.name.includes(e.target.value))
    );
    console.log(filtered);
    // prints an empty array on every key press
  };
  const handleSearch = (e) => {
    const filtered = chats.filter((chat) =>
      chat.users.filter((user) => user.name.includes(e.target.value))
    );
    console.log(filtered);
   // prints both objects (chats) on every keypress
  };

预期成绩

  • 如果输入值为“bat”,我希望返回 ID 为 2 的聊天
[{
    id: "2",
    isGroupChat: true,
    users: [
      {
        id: "193",
        name: "Johhny Dang",
        verified: false
      },
      {
        id: "496",
        name: "Batman",
        verified: true
      }
    ]
  }]
  

第二种方法似乎更接近您想要完成的目标。 您可能仍需要解决两个问题:

  1. 名称中的搜索是否不区分大小写? 如果没有,你就没有处理。
  2. filter调用使用的 function 需要返回 boolean 值。 由于内部filter返回数组本身而不是 boolean 表达式,因此您的外部filter正在返回所有结果。 Javascript 将其转换为“真实”结果。

以下代码应更正这两个问题:

const filtered = chats.filter((chat) => {
    const searchValue = e.target.value.toLowerCase();
    return chat.users.filter((user) => user.name.toLowerCase().includes(searchValue)).length > 0;
});

如果您想要区分大小写,可以删除toLowerCase()调用。 .length > 0验证内部过滤器找到至少一个使用 substring 的用户,因此在外部过滤器调用中返回整个chat对象。

如果你想在输入bat时得到 object id 2 你应该转换为小写

const handleSearch = (e) => 
 chats.filter(chat =>
   chat.users.filter(user => user.name.toLowerCase().includes(e.target.value)).length
);

试试这个它应该工作

const handleSearch2 = (e) => {

    const filtered = chats.filter((chat) =>
      chat.users.some((user) => user.name.includes(e))
    );
    console.log(filtered);
};

过滤器需要一个谓词作为参数,或者换句话说,一个返回 boolean 的 function; 这里有些返回 boolean。 使用 map 作为第一次迭代是错误的,因为 map 创建了一个数组,该数组的元素数量与已应用于该数组的元素数量相同。

走简单的路线,你可以做到这一点。

它将首先遍历所有聊天,然后在每个聊天中检查用户的用户名是否包含传递给 function 的用户名。 如果是这样,聊天将被添加到过滤列表中。

请注意,我使用 toLowerCase() 以使搜索不区分大小写,您可以将其删除以使其区分大小写。

const handleSearch = (username) => {
    var filtered = [];

    chats.forEach((chat) => {
        chat.users.forEach((user) => {
            if (user.name.toLowerCase().includes(username.toLowerCase())) {
                filtered.push(chat);
            }
        });
    });
    
    console.log(filtered);
    return filtered;
}

handleSearch('bat');

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM