问题
I have got two arrays of objects. I want to filter data based on permissionObj.
This is coming from database. Here are arrays of sub-arrays in the permissionObj.
let permissionObj = [
{
"Deposit": [{
label: "can create",
value: "can_create"
},
]
},
{
"Journals": [{
label: "can create",
value: "can_create"
}]
},
{
"Dashboard": [{
label: "can view",
value: "can_view"
}]
},
]
this is static data. I want to compare this data based on permission.
const PubSidebar = [{
label: "Dashboard",
value: "can_view"
},
{
label: "OA deal",
content: [
{
label: "Deposit",
key: "Deposit",
value: "can_view"
},
{
label: "Corrections",
key: "Corrections",
value: "can_edit"
},
]
},
{
label: "Journal",
content: [{
label: "Add Journal",
key: "Journals",
value: "can_create"
},
]
},
];
Here is my PubSidebar , I need three types of filtering - if pubSidebar array of Objects then it will be filtering based on label.For examaple, Dashboard - if pubSidebar array of sub-array of objects, then filtering will be based label, key and value , For example, PermissionObj key: will be property name such as OA deal, Deposit, value : can_view or anything
My expected output would be :
const PubSidebar = [{
label: "Dashboard",
value: "can_view"
},
{
label: "OA deal",
content: [
{
label: "edit oadeal ",
key: "OA deal",
value: "can_edit"
},
{
label: "Deposit",
key: "Deposit",
value: "can_view"
},
]
},
{
label: "Journal",
content: [{
label: "Add Journal",
key: "Journals",
value: "can_create"
},
]
},
];
回答1:
You can gain of reduce
method as it allows to write complex logic and decide what should be done on each iteration of an array. I slightly edited your source data as it is hard to understand the logic of filtering.
At first, we create an object which will contain filter data. Why object? As object has O(1)
to access to their keys.
const filterObject = permissionObj.reduce((a, c) => {
for (const key in c) {
a[key] = c[key];
}
return a;
},{});
Then we use reduce
method to decide whether the array element is eligible to be pushed:
const result = PubSidebar.reduce((a, c)=> {
if (filterObject[c.label] && c.value
&& filterObject[c.label].some(s => s.value == c.value) ) {
a.push(c);
}
else if (c.content.some(s => filterObject[s.key]) && c.content) {
c.content = c.content.filter(f => filterObject[f.key]
&& filterObject[f.key].some(s => s.value == f.value));
a.push(c);
}
return a;
}, [])
An example:
let permissionObj = [
{
"OA deal": [{
label: "can view",
value: "can_view"
}
]
}, {
"Deposit": [{
label: "can edit",
value: "can_edit"
},
]
},
{
"Deposit": [{
label: "can_view",
value: "can_view"
},
]
},
{
"Journals": [{
label: "can create",
value: "can_create"
}]
},
{
"Dashboard": [{
label: "can view",
value: "can_view"
}]
}
];
const PubSidebar = [
{
label: "Dashboard",
value: "can_view"
},
{
label: "OA deal",
content: [
{
label: "view oadeal",
key: "OA deal",
value: "can_view"
},
{
label: "Deposit",
key: "Deposit",
value: "can_view"
},
{
label: "Corrections",
key: "Corrections",
value: "can_edit"
},
]
},
{
label: "Journal",
content: [{
label: "Add Journal",
key: "Journals",
value: "can_create"
},
]
},
];
const filterObject = permissionObj.reduce((a, c) => {
for (const key in c) {
a[key] = c[key];
}
return a;
},{});
const result = PubSidebar.reduce((a, c)=> {
if (filterObject[c.label] && c.value
&& filterObject[c.label].some(s => s.value == c.value) ) {
a.push(c);
}
else if (c.content.some(s => filterObject[s.key]) && c.content) {
c.content = c.content.filter(f => filterObject[f.key]
&& filterObject[f.key].some(s => s.value == f.value));
a.push(c);
}
return a;
}, [])
console.log(result);
来源:https://stackoverflow.com/questions/60937465/how-to-filtering-array-of-sub-array-of-objects-and-array-of-sub-array-of-objects