过滤嵌套的 JSON 对象
filter a nested JSON object
我有一个搜索栏,您可以在其中输入员工姓名,它应该 return 基于过滤器的姓名。我有一个嵌套的 JSON 对象(如下所示),我需要在其中钻取该对象以访问数组中的员工姓名。
你可以看到我尝试实现的多个选项(它们被注释掉了)
我的问题是代码没有过滤名称并且 returning 所有名称而不是搜索的名称。我收到此错误 TypeError: Cannot read property 'filter' of undefined
以下代码用于访问另一个组件中的员工姓名:
{test.map((result) => (result.details.map((innerArr) =>
<h5>{innerArr.employee}</h5>
)))}
如何在下面的代码中实现上面的内容
const SearchByEmpComp = () => {
const [company, setCompany] = useState([
{
"company": "HIJ",
"_id": "610aeaec618ac5902c466541",
"details":
[
{
"employee": "Lesley Peden",
"notes": "Lesley's note",
"_id": "610aeaec618ac5902c466542"
},
{
"employee": "Wayne Smith",
"notes": "Wayne's note",
"_id": "610aeaec618ac5902c466543"
}
],
},
{
"company": "ABC",
"_id": "61003ff8e7684b709cf10da6",
"details":
[
{
"employee": "David Barton",
"notes": "some note!!",
"_id": "610aebb2618ac5902c46654e"
}
],
}
]);
//below code does not work
//attemp 1
const test = company.filter((r) =>
r.details.map((innerArr) => {
return innerArr.employee.toLowerCase().includes
(searchField.toLowerCase());
})
);
//attemp 1
// const test = company.map((el) => {
// return {...element, detail: element.detail.filter((details) =>
// details.employee.toLowerCase().includes
// (searchField.toLowerCase()))}
// })
//attemp 2
// const test = company.filter((res) => {
// return res.details.map((innerArr) =>
// innerArr.employee.toLowerCase().includes
// (searchField.toLowerCase()));
// });
//attemp 3
// const test = company.filter((comp) =>
// comp.details.employee.toLowerCase().includes(searchField.toLowerCase())
// );
const deatils = () => {
if (searchShow)
return <EmpDetailsByName test={test} />
}
};
return (
<>
<FormControl
type="search"
placeholder="Type Customer Name Here"
/>
<div>
<Button
onClick={handleClick}
>
Enter
</Button>
<div>{deatils()}</div>
</div
);
};
用于呈现名称的代码
const EmpDetailsByName = ({ test }) => {
return (
<>
{test.map((result) =>
(result.details.map((innerArr) =>
<h5>{innerArr.employee}</h5>
)))}
</>
);
};
export default EmpDetailsByName;
我不知道你的过滤器是如何应用的(它甚至过滤了什么?公司?IDs?),但实际上搜索功能应该像评论所建议的那样是它自己的小片段。
function SearchJsonForName(json,name) {
let result = []
for(company of json) {
for(employee of company.details) {
if(employee.name.match(name)) result.push(employee.name);
}
}
return result
}
这应该可以帮助您入门。如果您需要应用过滤器(也许是过滤公司?),您应该在搜索数组之前应用它(或者修改函数以使用过滤器 ;>)。
对于就地修改数组的版本:
function FilterByName(json,name) {
return json.map(company => {
let result = company.details.filter(employee =>
employee.name.match(name)));
return result.length > 0 ? {...company,details:result} : false;
}).filter(good => good);
};
除了 Werlious 的回答之外,如果您正在寻找仍包含在内的公司,那么您可以按此处所示进行映射。第一个映射仍然 return 家公司的所有员工都被过滤掉了。第二个映射将过滤掉没有任何详细信息的公司。
第三种是更现代的方法,只 return 员工。但是有无数的变体可以用于此。
const company = [
{
company: "HIJ",
_id: "610aeaec618ac5902c466541",
details: [
{
employee: "Lesley Peden",
notes: "Lesley's note",
_id: "610aeaec618ac5902c466542",
},
{
employee: "Wayne Smith",
notes: "Wayne's note",
_id: "610aeaec618ac5902c466543",
},
],
},
{
company: "ABC",
_id: "61003ff8e7684b709cf10da6",
details: [
{
employee: "Lesley Peden",
notes: "some note!!",
_id: "610aebb2618ac5902c46654e",
},
],
},
];
const searchField = "les";
//attemp 1
const test = company.map((element) => {
return {
...element,
details: element.details.filter((details) =>
details.employee.toLowerCase().includes(searchField.toLowerCase())
),
};
});
console.log("test", test);
const test2 = company
.map((company) => {
let details = company.details.filter((detail) =>
detail.employee.toLowerCase().includes(searchField.toLowerCase())
);
if (!details.length) {
return null;
}
return { ...company, details };
})
.filter(Boolean);
console.log("test2", test2);
// Modern browser version of filtering to only the employees :)
const test3 = company.flatMap((company) =>
company.details.filter((detail) =>
detail.employee.toLowerCase().includes(searchField.toLowerCase())
)
);
console.log("test3", test3);
我举了一个例子,说明如何使用输入文本过滤 json
看一下状态的使用以及如何访问公司
所以我有一个使用 Regex 的简单解决方案,
employeeArray = [
{
company: "HIJ",
_id: "610aeaec618ac5902c466541",
details: [
{
employee: "Lesley Peden",
notes: "Lesley's note",
_id: "610aeaec618ac5902c466542",
},
{
employee: "Wayne Smith",
notes: "Wayne's note",
_id: "610aeaec618ac5902c466543",
},
],
},
{
company: "ABC",
_id: "61003ff8e7684b709cf10da6",
details: [
{
employee: "David Barton",
notes: "some note!!",
_id: "610aebb2618ac5902c46654e",
},
],
},
];
// Set the state of the search string using state
let searchUser = "Les";
// converting the search string to regex
let convertedName = new RegExp(`.*${searchUser}.*`);
searchResults = employeeArray
.map((element) => {
return {
...element,
details: element.details.filter((employee) => {
// Filtering based on the Regex
return convertedName.test(employee.employee);
}),
};
})
// filtering based on the length of the data array length
.filter((element) => element.details.length > 0);
console.log(searchResults);
说明 : 所以根据你的情况,
- 我们先获取用户输入,然后将它们转换为正则表达式,这样我们就得到了所有推荐的名字。
- Filter,所以对于
Array.map
,我们首先直接对数组应用一个高级映射,然后我们关注内部细节数组并应用一个也对此进行过滤,我已经根据数据的存在将 return 设为布尔值,
- 所以我们要做的是 MAP-> [OBJECTS -> [FILTER[DETAILS]]],所以,现在我们会过滤每个 JSON 中的每个细节数组,然后过滤他们基于细节数组的长度,所以,我们最终得到了完整的对象。结果将如预期。
搜索字符串输出设置为“LES”
[
{
company: 'HIJ',
_id: '610aeaec618ac5902c466541',
details: [
{
employee: 'Lesley Peden',
notes: "Lesley's note",
_id: '610aeaec618ac5902c466542'
}
]
}
]
这将帮助您提出对给定名称的所有建议。数组[对象]
我有一个搜索栏,您可以在其中输入员工姓名,它应该 return 基于过滤器的姓名。我有一个嵌套的 JSON 对象(如下所示),我需要在其中钻取该对象以访问数组中的员工姓名。
你可以看到我尝试实现的多个选项(它们被注释掉了)
我的问题是代码没有过滤名称并且 returning 所有名称而不是搜索的名称。我收到此错误 TypeError: Cannot read property 'filter' of undefined
以下代码用于访问另一个组件中的员工姓名:
{test.map((result) => (result.details.map((innerArr) =>
<h5>{innerArr.employee}</h5>
)))}
如何在下面的代码中实现上面的内容
const SearchByEmpComp = () => {
const [company, setCompany] = useState([
{
"company": "HIJ",
"_id": "610aeaec618ac5902c466541",
"details":
[
{
"employee": "Lesley Peden",
"notes": "Lesley's note",
"_id": "610aeaec618ac5902c466542"
},
{
"employee": "Wayne Smith",
"notes": "Wayne's note",
"_id": "610aeaec618ac5902c466543"
}
],
},
{
"company": "ABC",
"_id": "61003ff8e7684b709cf10da6",
"details":
[
{
"employee": "David Barton",
"notes": "some note!!",
"_id": "610aebb2618ac5902c46654e"
}
],
}
]);
//below code does not work
//attemp 1
const test = company.filter((r) =>
r.details.map((innerArr) => {
return innerArr.employee.toLowerCase().includes
(searchField.toLowerCase());
})
);
//attemp 1
// const test = company.map((el) => {
// return {...element, detail: element.detail.filter((details) =>
// details.employee.toLowerCase().includes
// (searchField.toLowerCase()))}
// })
//attemp 2
// const test = company.filter((res) => {
// return res.details.map((innerArr) =>
// innerArr.employee.toLowerCase().includes
// (searchField.toLowerCase()));
// });
//attemp 3
// const test = company.filter((comp) =>
// comp.details.employee.toLowerCase().includes(searchField.toLowerCase())
// );
const deatils = () => {
if (searchShow)
return <EmpDetailsByName test={test} />
}
};
return (
<>
<FormControl
type="search"
placeholder="Type Customer Name Here"
/>
<div>
<Button
onClick={handleClick}
>
Enter
</Button>
<div>{deatils()}</div>
</div
);
};
用于呈现名称的代码
const EmpDetailsByName = ({ test }) => {
return (
<>
{test.map((result) =>
(result.details.map((innerArr) =>
<h5>{innerArr.employee}</h5>
)))}
</>
);
};
export default EmpDetailsByName;
我不知道你的过滤器是如何应用的(它甚至过滤了什么?公司?IDs?),但实际上搜索功能应该像评论所建议的那样是它自己的小片段。
function SearchJsonForName(json,name) {
let result = []
for(company of json) {
for(employee of company.details) {
if(employee.name.match(name)) result.push(employee.name);
}
}
return result
}
这应该可以帮助您入门。如果您需要应用过滤器(也许是过滤公司?),您应该在搜索数组之前应用它(或者修改函数以使用过滤器 ;>)。
对于就地修改数组的版本:
function FilterByName(json,name) {
return json.map(company => {
let result = company.details.filter(employee =>
employee.name.match(name)));
return result.length > 0 ? {...company,details:result} : false;
}).filter(good => good);
};
除了 Werlious 的回答之外,如果您正在寻找仍包含在内的公司,那么您可以按此处所示进行映射。第一个映射仍然 return 家公司的所有员工都被过滤掉了。第二个映射将过滤掉没有任何详细信息的公司。
第三种是更现代的方法,只 return 员工。但是有无数的变体可以用于此。
const company = [
{
company: "HIJ",
_id: "610aeaec618ac5902c466541",
details: [
{
employee: "Lesley Peden",
notes: "Lesley's note",
_id: "610aeaec618ac5902c466542",
},
{
employee: "Wayne Smith",
notes: "Wayne's note",
_id: "610aeaec618ac5902c466543",
},
],
},
{
company: "ABC",
_id: "61003ff8e7684b709cf10da6",
details: [
{
employee: "Lesley Peden",
notes: "some note!!",
_id: "610aebb2618ac5902c46654e",
},
],
},
];
const searchField = "les";
//attemp 1
const test = company.map((element) => {
return {
...element,
details: element.details.filter((details) =>
details.employee.toLowerCase().includes(searchField.toLowerCase())
),
};
});
console.log("test", test);
const test2 = company
.map((company) => {
let details = company.details.filter((detail) =>
detail.employee.toLowerCase().includes(searchField.toLowerCase())
);
if (!details.length) {
return null;
}
return { ...company, details };
})
.filter(Boolean);
console.log("test2", test2);
// Modern browser version of filtering to only the employees :)
const test3 = company.flatMap((company) =>
company.details.filter((detail) =>
detail.employee.toLowerCase().includes(searchField.toLowerCase())
)
);
console.log("test3", test3);
我举了一个例子,说明如何使用输入文本过滤 json
看一下状态的使用以及如何访问公司
所以我有一个使用 Regex 的简单解决方案,
employeeArray = [
{
company: "HIJ",
_id: "610aeaec618ac5902c466541",
details: [
{
employee: "Lesley Peden",
notes: "Lesley's note",
_id: "610aeaec618ac5902c466542",
},
{
employee: "Wayne Smith",
notes: "Wayne's note",
_id: "610aeaec618ac5902c466543",
},
],
},
{
company: "ABC",
_id: "61003ff8e7684b709cf10da6",
details: [
{
employee: "David Barton",
notes: "some note!!",
_id: "610aebb2618ac5902c46654e",
},
],
},
];
// Set the state of the search string using state
let searchUser = "Les";
// converting the search string to regex
let convertedName = new RegExp(`.*${searchUser}.*`);
searchResults = employeeArray
.map((element) => {
return {
...element,
details: element.details.filter((employee) => {
// Filtering based on the Regex
return convertedName.test(employee.employee);
}),
};
})
// filtering based on the length of the data array length
.filter((element) => element.details.length > 0);
console.log(searchResults);
说明 : 所以根据你的情况,
- 我们先获取用户输入,然后将它们转换为正则表达式,这样我们就得到了所有推荐的名字。
- Filter,所以对于
Array.map
,我们首先直接对数组应用一个高级映射,然后我们关注内部细节数组并应用一个也对此进行过滤,我已经根据数据的存在将 return 设为布尔值, - 所以我们要做的是 MAP-> [OBJECTS -> [FILTER[DETAILS]]],所以,现在我们会过滤每个 JSON 中的每个细节数组,然后过滤他们基于细节数组的长度,所以,我们最终得到了完整的对象。结果将如预期。
搜索字符串输出设置为“LES”
[
{
company: 'HIJ',
_id: '610aeaec618ac5902c466541',
details: [
{
employee: 'Lesley Peden',
notes: "Lesley's note",
_id: '610aeaec618ac5902c466542'
}
]
}
]
这将帮助您提出对给定名称的所有建议。数组[对象]