我很难根据嵌套对象数组中的值过滤对象数组。我有一个聊天应用程序,其中一个组件呈现用户拥有的聊天列表。我希望能够在用户输入输入元素时按名称过滤聊天记录。
这是数组或初始状态的示例:
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
}
]
}
];
我希望能够按用户名称进行搜索,如果名称存在于其中一个对象(聊天)中,则返回整个对象。
这是我尝试过但没有结果的方法
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
};
预期结果
[{
id: "2",
isGroupChat: true,
users: [
{
id: "193",
name: "Johhny Dang",
verified: false
},
{
id: "496",
name: "Batman",
verified: true
}
]
}]
答案 0 :(得分:2)
第二种方法似乎更接近您要实现的目标。您可能仍需要解决两个问题:
filter
调用使用的函数需要返回一个布尔值。由于内部 filter
返回数组本身而不是布尔表达式,因此您的外部 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
验证内部过滤器至少找到了一个具有子字符串的用户,因此在外部过滤器调用中返回整个 chat
对象。
答案 1 :(得分:1)
如果你想在输入 bat 时得到对象 id 2 你应该转换成小写
const handleSearch = (e) =>
chats.filter(chat =>
chat.users.filter(user => user.name.toLowerCase().includes(e.target.value)).length
);
试试这个应该可以的
答案 2 :(得分:0)
const handleSearch2 = (e) => {
const filtered = chats.filter((chat) =>
chat.users.some((user) => user.name.includes(e))
);
console.log(filtered);
};
filter 需要一个谓词作为参数,或者换句话说,一个返回布尔值的函数;这里 some 返回一个布尔值。 使用 map 作为第一次迭代是错误的,因为 map 创建了一个数组,该数组的元素数量与所应用的数组元素数量相同。
答案 3 :(得分:0)
走简单的路线,你可以做到这一点。
它将首先循环所有聊天,然后在每个聊天中检查用户的用户名是否包含传递给函数的用户名。如果是这样,聊天将被添加到过滤列表中。
注意,我使用 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');