I want to filter items from the categories
array based on the criteria in the otherCategories
array.
If otherCategories
contains an object where title
matches one title from categories.subCategory[i].title
and name
matches categories.subCategory[i].details.name
, then filter only that object eg "item1" from categories
.
var categories = [
{
title:"item1",
subCategory:[
{
title:"subCat1",
details:{
name:"detail1",
email:"test@test.com"
}
},
{
title:"subCat2",
details:{
name:"detail2",
email:"test@test.com"
}
}
]
},
{
title:"item2",
subCategory:[
{
title:"subCat1",
details:{
name:"detail3",
email:"test@test.com"
}
},
{
title:"subCat2",
details:{
name:"detail2",
email:"test@test.com"
}
}
]
}
]
var otherCategories = [
{
title:"subCat1",
name:"detail1"
}
]
Expected result
categories = [
{
title:"item1",
subCategory:[
{
title:"subCat1",
details:{
name:"detail1",
email:"test@test.com"
}
},
{
title:"subCat2",
details:{
name:"detail2",
email:"test@test.com"
}
}
]
}]
Use Array.reduce , Array.filter & Array.some
otherCategories
array to an object with title as key and name as value categories
array where some subCategory
exists with matching values var categories = [{title:"item1",subCategory:[{title:"subCat1",details:{name:"detail1",email:"test@test.com"}},{title:"subCat2",details:{name:"detail2",email:"test@test.com"}}]},{title:"item2",subCategory:[{title:"subCat1",details:{name:"detail3",email:"test@test.com"}},{title:"subCat2",details:{name:"detail2",email:"test@test.com"}}]}]; var otherCategories = [{title:"subCat1",name:"detail1"}]; var obj = otherCategories.reduce((a,c) => Object.assign(a,{[c.title]:c.name}), {}); categories = categories.filter(v => v.subCategory.some(o => obj[o.title] === o.details.name)); console.log(categories);
Another approach that will usually work for simple objects like the ones in your example, is to convert your otherCategories
array to an array of "stringified" objects, and then filter categories
by comparing "stringified" versions of the desired subCategory
key value pairs to the converted otherCategories
array.
Important to note, however, that object property order is not guaranteed in JavaScript (although many browsers will preserve property order). That means that this approach may not work in some situations and an approach like the one suggested by @NikhilAggarwal is more stable.
For example:
const categories = [{title: "item1", subCategory: [{title: "subCat1", details: {name: "detail1", email: "test@test.com"}},{title: "subCat2", details: {name: "detail2", email: "test@test.com"}}]}, {title: "item2", subCategory: [{title: "subCat1", details: {name: "detail3", email: "test@test.com"}},{title: "subCat2", details: {name: "detail2", email: "test@test.com"}}]}]; const otherCategories = [{title: "subCat1", name: "detail1"}]; let matches = otherCategories.map((item) => JSON.stringify(item)); let results = categories.filter((item) => { for (let sub of item.subCategory) { let match = JSON.stringify({title: sub.title, name: sub.details.name}); if (matches.includes(match)) { return item; } } }); console.log(results);
You could map
the categories to the results by filtering
the subCategories:
function matches(sub, filters) {
return filters.some(filter => filter.title === sub.title && filter.name === sub.name);
}
const result = categories.map(({ title, subCategories }) => ({ title, subCategories: subCategories.filter(sub => matches(sub, otherCategories)) }));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.