'How to filter an object array if the value of an object match array [duplicate]
I have the following object table :
let data = [
{key:"20-09-2019", skill: [{id: 500, message: "monday"}, {id: 501, message: "tuesday"}]},
{key:"21-09-2019", skill: [{id: 502, message: "thursday"}, {id: 503, message: "sunday"}]},
{key:"22-09-2019", skill: [{id: 504, message: "sunday"}]},
]
let search = "sun"
I would like to filter the table if the value of "message" match with the value of "search"
if search = "sun" the filter should return the following result:
result after filter :
data = [
{key:"21-09-2019", skill: [ {id: 503, message: "sunday"}]},
{key:"22-09-2019", skill: [{id: 504, message: "sunday"}]},
]
here the array only returns the objects having the message value that match with "sun"
I know the filter method but I do not think we can do a filter in a filter.
I also know the method that allows me to match the message :
message.toLowerCase().includes(search);
but I do not know how to filter the object array, if anyone has an idea?
Solution 1:[1]
You can filter on skill field of each element by search value first then filter elements that still have skill.
let search = "sun";
let data = [
{key:"20-09-2019", skill: [{id: 500, message: "monday"}, {id: 501, message: "tuesday"}]},
{key:"21-09-2019", skill: [{id: 502, message: "thursday"}, {id: 503, message: "sunday"}]},
{key:"22-09-2019", skill: [{id: 504, message: "sunday"}]},
];
data.forEach(el => {
el.skill = el.skill.filter(s => s.message.toLowerCase().includes(search))
});
let result = data.filter(el => el.skill.length);
console.log(result)
Edit for not mutate the original array:
let search = "sun";
let data = [
{key:"20-09-2019", skill: [{id: 500, message: "monday"}, {id: 501, message: "tuesday"}]},
{key:"21-09-2019", skill: [{id: 502, message: "thursday"}, {id: 503, message: "sunday"}]},
{key:"22-09-2019", skill: [{id: 504, message: "sunday"}]},
];
let result = data.reduce((acc, {skill, ...rest}) => {
skill = skill.filter(s => s.message.toLowerCase().includes(search));
if(skill.length) acc.push({skill, ...rest});
return acc;
}, []);
console.log(result);
Solution 2:[2]
I do not think we can do a filter in a filter.
Yes you can but I would use forEach(). Example below.
let data = [
{key:"20-09-2019", skill: [{id: 500, message: "monday"}, {id: 501, message: "tuesday"}]},
{key:"21-09-2019", skill: [{id: 502, message: "thursday"}, {id: 503, message: "sunday"}]},
{key:"22-09-2019", skill: [{id: 504, message: "sunday"}]},
]
let search = 'sunday';
let result = [];
data.forEach(row=>{
let found = row.skill.filter((skill=>skill.message === search));
if (found.length) result.push({key:row.key,skill:found});
})
console.log(result);
Solution 3:[3]
You can do it this way
let data = [
{key:"20-09-2019", skill: [{id: 500, message: "monday"}, {id: 501, message: "tuesday"}]},
{key:"21-09-2019", skill: [{id: 502, message: "thursday"}, {id: 503, message: "sunday"}]},
{key:"22-09-2019", skill: [{id: 504, message: "sunday"}]},
];
let search = "sun"
const newItems = data.filter(item => item.skill.filter(sk => sk.message.includes(search)).length);
newItems.forEach(item => {
item.skill = item.skill.filter(x => x.message.includes(search))
})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 |
