Related
I am still in the midst of learning React and Javascript and have came to a roadblock with my current project.
Project goal
I am trying to map through two array of objects, and check if a certain property matches.
if recommendedSkillTree.skills.skill === currentSkills.skill, I would then like to check if recommendedSkillTree.skills.level > currentSkills.level.
if the above condition matches, or if currentSkills.skill do not have the skills in the recommendedSkillTree Data, the skill will then show up in a red text. Else, green text.
What I have done
I have tried mapping between the 2 arrays to check if currentSkills.skill === recommendedSkillTree.skills.skill.
const skillMatch = recommendedSkillTree.filter((skillRecommended) =>
currentSkills.some((skillCurrent) => skillRecommended.skills.skill === skillCurrent.skill)
);
.
.
.
return (
<div>
{recommendedSkillTree.map((item, i) => (
<div key={item.id}>
<div
style={{
color: !skillMatch[i] ? "red" : "green",
}}
>
{item.skill}
</div>
</div>
))}
</div>
By doing so, I am able to churn out an output where skills that are present in currentSkills are shown in green, and those that are not in it are shown in red.
Next I would like to go one step deeper, and tried to compare the skill level of the present skills, and if they fall short of the recommended level, the text would then show in red.
const levelGap = recommendedSkillTree.map((recommendedLevel) =>
currentSkills.some((levelCurrent) => recommendedLevel.level > levelCurrent.level)
);
By doing so, I would be expecting an output of
[true, false, true, true, true, true, true, true, true]
instead I've got:
[true, true, true, true, false, true, true, false, false]
I am unable to see which part have went wrong. Would greatly appreciate if any seniors in this field would guide me along.
Data 1
const recommendedSkillTree = [
{
id: "1",
role: "Paladin",
skills: [
{
id: "1",
skill: "Attack",
level: "3",
},
{
id: "2",
skill: "Block",
level: "3",
},
{
id: "3",
skill: "Taunt",
level: "3",
},
{
id: "4",
skill: "Heal",
level: "4",
},
{
id: "5",
skill: "Group Heal",
level: "2",
},
{
id: "6",
skill: "Double Attack",
level: "4",
},
{
id: "7",
skill: "Ultimate",
level: "3",
},
{
id: "8",
skill: "Defense Up",
level: "2",
},
{
id: "9",
skill: "Attack Up",
level: "2",
},
],
},
];
export default recommendedSkillTree;
Data 2
const currentSkills = [
{
id: "1",
skill: "Attack",
level: "2",
},
{
id: "2",
skill: "Block",
level: "3",
},
{
id: "3",
skill: "Taunt",
level: "2",
},
{
id: "4",
skill: "Heal",
level: "3",
},
{
id: "5",
skill: "Final Slash",
level: "3",
},
];
export default currentSkills;
Thank you in advance for your time, and I do apologize if my way of asking questions are not up to community standard as this is my first time posting on here.
I do not really have anyone around me to ask questions on since I am fully self-taught and no one around me is in the tech field. Thank you so much.
This may be one possible solution to achieve the desired objective.
Code Snippet
const isGreenOrRed = (reco, curr) => (
reco.skills.map(re => (
curr.some(({skill}) => skill === re.skill)
? curr.find(({skill}) => skill === re.skill)['level'] >= re.level
? 'green'
: 'red'
: 'red'
))
);
const recommendedSkillTree = [
{
id: "1",
role: "Paladin",
skills: [
{
id: "1",
skill: "Attack",
level: "3",
},
{
id: "2",
skill: "Block",
level: "3",
},
{
id: "3",
skill: "Taunt",
level: "3",
},
{
id: "4",
skill: "Heal",
level: "4",
},
{
id: "5",
skill: "Group Heal",
level: "2",
},
{
id: "6",
skill: "Double Attack",
level: "4",
},
{
id: "7",
skill: "Ultimate",
level: "3",
},
{
id: "8",
skill: "Defense Up",
level: "2",
},
{
id: "9",
skill: "Attack Up",
level: "2",
},
],
},
];
const currentSkills = [
{
id: "1",
skill: "Attack",
level: "2",
},
{
id: "2",
skill: "Block",
level: "3",
},
{
id: "3",
skill: "Taunt",
level: "2",
},
{
id: "4",
skill: "Heal",
level: "3",
},
{
id: "5",
skill: "Final Slash",
level: "3",
},
];
console.log(isGreenOrRed(recommendedSkillTree[0], currentSkills).join(", "));
const SomeComp = ({getColor, ...props}) => (
<div>
{recommendedSkillTree[0].skills.map((item, i) => (
<div key={item.id}>
<div
style={{
color: getColor[i]
}}
>
{item.skill}
</div>
</div>
))}
</div>
);
ReactDOM.render(
<div>
<h4>Demo UI</h4>
<SomeComp getColor={isGreenOrRed(recommendedSkillTree[0], currentSkills)}/>
</div>,
document.getElementById('rd')
);
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
Explanation
this uses the same logic as attempted by OP in the question
fixes some of the issues faced
Below solution employs an alternative approach to get the same result.
Code Snippet
const isGreenOrRed = (needle, haystack) => (
haystack.some(({skill}) => skill === needle.skill)
? haystack.find(({skill}) => skill === needle.skill)['level'] >= needle.level
? 'green'
: 'red'
: 'red'
);
const recommendedSkillTree = [
{
id: "1",
role: "Paladin",
skills: [
{
id: "1",
skill: "Attack",
level: "3",
},
{
id: "2",
skill: "Block",
level: "3",
},
{
id: "3",
skill: "Taunt",
level: "3",
},
{
id: "4",
skill: "Heal",
level: "4",
},
{
id: "5",
skill: "Group Heal",
level: "2",
},
{
id: "6",
skill: "Double Attack",
level: "4",
},
{
id: "7",
skill: "Ultimate",
level: "3",
},
{
id: "8",
skill: "Defense Up",
level: "2",
},
{
id: "9",
skill: "Attack Up",
level: "2",
},
],
},
];
const currentSkills = [
{
id: "1",
skill: "Attack",
level: "2",
},
{
id: "2",
skill: "Block",
level: "3",
},
{
id: "3",
skill: "Taunt",
level: "2",
},
{
id: "4",
skill: "Heal",
level: "3",
},
{
id: "5",
skill: "Final Slash",
level: "3",
},
];
console.log(recommendedSkillTree[0].skills.map(it => isGreenOrRed(it, currentSkills)).join(", "));
const SomeComp = () => (
<div>
{recommendedSkillTree[0].skills.map(item => (
<div key={item.id}>
<div
style={{
color: isGreenOrRed(item, currentSkills)
}}
>
{item.skill}
</div>
</div>
))}
</div>
);
ReactDOM.render(
<div>
<h4>Demo UI - Alternate Approach</h4>
<SomeComp />
</div>,
document.getElementById('rd')
);
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
Explanation
This pushes the validation at the individual skill object level
Thus, re-using the existing .map iteration happening in the JSX
Here's an example using Lodash map. You can try play around with the check function to get the desired result.
const recommendedSkillTree = [{
id: "1",
role: "Paladin",
skills: [{
id: "1",
skill: "Attack",
level: "3",
},
{
id: "2",
skill: "Block",
level: "3",
},
{
id: "3",
skill: "Taunt",
level: "3",
},
{
id: "4",
skill: "Heal",
level: "4",
},
{
id: "5",
skill: "Group Heal",
level: "2",
},
{
id: "6",
skill: "Double Attack",
level: "4",
},
{
id: "7",
skill: "Ultimate",
level: "3",
},
{
id: "8",
skill: "Defense Up",
level: "2",
},
{
id: "9",
skill: "Attack Up",
level: "2",
},
],
}];
const currentSkills = [{
id: "1",
skill: "Attack",
level: "2",
},
{
id: "2",
skill: "Block",
level: "3",
},
{
id: "3",
skill: "Taunt",
level: "2",
},
{
id: "4",
skill: "Heal",
level: "3",
},
{
id: "5",
skill: "Final Slash",
level: "3",
},
];
var result = [];
function check(skill) {
var found = _.find(currentSkills, function(o) {
return o.skill === skill.skill;
});
if (found) {
result.push(found.level >= skill.level);
} else {
result.push(false);
}
}
_.map(recommendedSkillTree[0].skills, check);
console.log(result);
<script src="https://lodash.com/vendor/cdn.jsdelivr.net/npm/lodash#4.17.15/lodash.min.js"></script>
I want to remove duplicates from an array of objects can anyone help with this to remove duplicates in the array of objects. I have an array of array of objects that I want to remove duplicates and I want to use
const firstArray = [
{
first: "01",
data: [
{ id: "01", name: "test1" },
{ id: "02", name: "test2" },
{ id: "03", name: "test3" },
{ id: "05", name: "test1" },
{ id: "06", name: "test2" },
{ id: "07", name: "test1" }
]
},
{
first: "02",
data: [
{ id: "01", name: "test2" },
{ id: "02", name: "test1" },
{ id: "03", name: "test3" },
{ id: "05", name: "test2" },
{ id: "06", name: "test2" },
{ id: "07", name: "test1" }
]
},
{
first: "03",
data: [
{ id: "01", name: "test3" },
{ id: "02", name: "test2" },
{ id: "03", name: "test3" },
{ id: "04", name: "test2" },
{ id: "05", name: "test3" },
{ id: "07", name: "test1" }
]
}
];
this is the sample result code i am expecting :
const firstArray = [
{
first: "01",
data: [
{ id: "01", name: "test1" },
{ id: "02", name: "test2" },
{ id: "03", name: "test3" },
]
},
{
first: "02",
data: [
{ id: "01", name: "test1" },
{ id: "02", name: "test2" },
{ id: "03", name: "test3" },
]
},
{
first: "03",
data: [
{ id: "05", name: "test1" },
{ id: "06", name: "test2" },
{ id: "07", name: "test3" }
]
}
];```
this way..
const firstArray =
[ { first: '01'
, data:
[ { id: '01', name: 'test1' }
, { id: '02', name: 'test2' }
, { id: '03', name: 'test3' }
, { id: '05', name: 'test1' }
, { id: '06', name: 'test2' }
, { id: '07', name: 'test1' }
] }
, { first: '02'
, data:
[ { id: '01', name: 'test2' }
, { id: '02', name: 'test1' }
, { id: '03', name: 'test3' }
, { id: '05', name: 'test2' }
, { id: '06', name: 'test2' }
, { id: '07', name: 'test1' }
] }
, { first: '03'
, data:
[ { id: '01', name: 'test3' }
, { id: '02', name: 'test2' }
, { id: '03', name: 'test3' }
, { id: '04', name: 'test2' }
, { id: '05', name: 'test3' }
, { id: '07', name: 'test1' }
] } ]
firstArray.forEach(({data})=>
{
for (let i=data.length;--i>0;)
if (data.findIndex(({name})=>name===data[i].name) < i)
data.splice(i,1)
})
console.log( JSON.stringify( firstArray,0,2))
.as-console-wrapper {max-height: 100%!important;top:0 }
const firstArray = [
{
first: "01",
data: [
{ id: "01", name: "test1" },
{ id: "02", name: "test2" },
{ id: "03", name: "test3" },
{ id: "05", name: "test1" },
{ id: "06", name: "test2" },
{ id: "07", name: "test1" }
]
},
{
first: "02",
data: [
{ id: "01", name: "test2" },
{ id: "02", name: "test1" },
{ id: "03", name: "test3" },
{ id: "05", name: "test2" },
{ id: "06", name: "test2" },
{ id: "07", name: "test1" }
]
},
{
first: "03",
data: [
{ id: "01", name: "test3" },
{ id: "02", name: "test2" },
{ id: "03", name: "test3" },
{ id: "04", name: "test2" },
{ id: "05", name: "test3" },
{ id: "07", name: "test1" }
]
}
];
let filterValues = firstArray.map((item) => {
let data = item.data.filter(
(value, index, data) =>
data.findIndex((item) => item.name === value.name) === index
);
return { ...{ first: item.first }, data };
});
console.log(filterValues);
I have array of objects like below. Here children element may deeply nested, it may contain other children element as well.
let response = [{
id: 4321,
name: 'Education',
parentId: null,
children: [{
id: 1234,
name: 'category1',
parentId: 4321,
children: [{
id: 8327548,
name: '001',
parentId: 1234,
}, {
id: 8327549,
name: '002',
parentId: 1234,
}],
}, {
id: 6786,
name: 'Associations',
parentId: 4321,
}, {
id: 8262439,
name: 'category1',
parentId: 4321,
}, {
id: 8245,
name: 'Rights',
parentId: 4321,
children: [{
id: 2447,
name: 'Organizations',
parentId: 8245,
}, {
id: 9525,
name: 'Services',
parentId: 8245,
}, {
id: 8448,
name: 'Organizations',
parentId: 8245,
}],
}, {
id: 8262446,
name: 'Women\'s Rights',
parentId: 4321,
}],
}, {
id: 21610,
name: 'Agriculture',
parentId: null,
children: [{
id: 3302,
name: 'categoryABC',
parentId: 21610,
children: [{
id: 85379,
name: 'categoryABC - General',
parentId: 3302,
}, {
id: 85380,
name: 'categoryABC Technology',
parentId: 3302,
}],
}, {
id: 8303,
name: 'Fungicides',
parentId: 21610,
children: [{
id: 8503,
name: 'Fungicides - General',
parentId: 8303,
}],
}],
}];
I want to make it flat array of objects but I want to add parent name (which parentId is null) to every objects inside that respective parent.
expected output:
[
{
id: 8327548,
name: "001",
parentId: 1234
mainParent: "Education"
}, {
id: 8327549,
name: "002",
parentId: 1234,
mainParent: "Agriculture"
},
// ...OTHER OBJECTS....
]
What I have done so far
function flat(array) {
var result = [];
array.forEach(function (a) {
result.push(a);
if (Array.isArray(a.children)) {
result = result.concat(flat(a.children));
delete a.children;
}
});
return result;
}
It's giving the flat array of objects but I'm not able to add parent name property to every objects.
Can someone please help me?
You could take a recursive approach an handover the first found name as mainParent.
const
flat = mainParent => o => o.children
? o.children.flatMap(flat(mainParent || o.name))
: { ...o, mainParent },
response = [{ id: 4321, name: "Education", parentId: null, children: [{ id: 1234, name: "category1", parentId: 4321, children: [{ id: 8327548, name: "001", parentId: 1234 }, { id: 8327549, name: "002", parentId: 1234 }] }, { id: 6786, name: "Associations", parentId: 4321 }, { id: 8262439, name: "category1", parentId: 4321 }, { id: 8245, name: "Rights", parentId: 4321, children: [{ id: 2447, name: "Organizations", parentId: 8245 }, { id: 9525, name: "Services", parentId: 8245 }, { id: 8448, name: "Organizations", parentId: 8245 }] }, { id: 8262446, name: "Women's Rights", parentId: 4321 }] }, { id: 21610, name: "Agriculture", parentId: null, children: [{ id: 3302, name: "categoryABC", parentId: 21610, children: [{ id: 85379, name: "categoryABC - General", parentId: 3302 }, { id: 85380, name: "categoryABC Technology", parentId: 3302 }] }, { id: 8303, name: "Fungicides", parentId: 21610, children: [{ id: 8503, name: "Fungicides - General", parentId: 8303 }] }] }],
result = response.flatMap(flat());
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This is a fairly clean recursion, stopping when there are no children in the node. We capture the first name value found along the hierarchy and carry it through.
const flat = (xs, name = null) =>
xs .flatMap (x => x .children
? flat (x .children, name || x .name)
: [{...x, mainParent: name}]
)
const response = [{id: 4321, name: "Education", parentId: null, children: [{id: 1234, name: "category1", parentId: 4321, children: [{id: 8327548, name: "001", parentId: 1234}, {id: 8327549, name: "002", parentId: 1234}]}, {id: 6786, name: "Associations", parentId: 4321}, {id: 8262439, name: "category1", parentId: 4321}, {id: 8245, name: "Rights", parentId: 4321, children: [{id: 2447, name: "Organizations", parentId: 8245}, {id: 9525, name: "Services", parentId: 8245}, {id: 8448, name: "Organizations", parentId: 8245}]}, {id: 8262446, name: "Women's Rights", parentId: 4321}]}, {id: 21610, name: "Agriculture", parentId: null, children: [{id: 3302, name: "categoryABC", parentId: 21610, children: [{id: 85379, name: "categoryABC - General", parentId: 3302}, {id: 85380, name: "categoryABC Technology", parentId: 3302}]}, {id: 8303, name: "Fungicides", parentId: 21610, children: [{id: 8503, name: "Fungicides - General", parentId: 8303}]}]}]
console .log (flat (response))
.as-console-wrapper {max-height: 100% !important; top: 0}
Less obscure, but still fairly concise.
const response = [{ id: 4321, name: 'Education', parentId: null, children: [{ id: 1234, name: 'category1', parentId: 4321, children: [{ id: 8327548, name: '001', parentId: 1234 }, { id: 8327549, name: '002', parentId: 1234 }] }, { id: 6786, name: 'Associations', parentId: 4321 }, { id: 8262439, name: 'category1', parentId: 4321 }, { id: 8245, name: 'Rights', parentId: 4321, children: [{ id: 2447, name: 'Organizations', parentId: 8245 }, { id: 9525, name: 'Services', parentId: 8245 }, { id: 8448, name: 'Organizations', parentId: 8245 }] }, { id: 8262446, name: 'Women\'s Rights', parentId: 4321 }] }, { id: 21610, name: 'Agriculture', parentId: null, children: [{ id: 3302, name: 'categoryABC', parentId: 21610, children: [{ id: 85379, name: 'categoryABC - General', parentId: 3302 }, { id: 85380, name: 'categoryABC Technology', parentId: 3302 }] }, { id: 8303, name: 'Fungicides', parentId: 21610, children: [{ id: 8503, name: 'Fungicides - General', parentId: 8303 }] }] }];
function flatten(arr, mainParent = null) {
if (!arr) return;
let result = [];
for (const obj of arr) {
result.push(...(flatten(obj.children, mainParent ?? obj.name) ?? [{ ...obj, mainParent }]));
}
return result;
}
console.log(flatten(response));
.as-console-wrapper { max-height: 100% !important; top: 0; }
A possible solution could be based entirely on a single, though recursively implemented, reduce task, where the accumulating and recursively passed down object carries both information, the mainParent value and the recursively collected final result ...
function recursivelyReassambleAndCollectChildlessItems(
{ mainParent, result }, { children, ...item }
) {
result = result.concat(children && children.reduce(
recursivelyReassambleAndCollectChildlessItems, {
// was:
// mainParent: mainParent ?? item.name,
/**
* OP quote:
* "... but I want to add parent name
* (which parentId is null) to every
* objects inside that respective parent."
*/
mainParent: item.parentId === null ? item.name : mainParent,
result: [],
}
).result || { mainParent, ...item });
return { mainParent, result };
}
const response = [{
id: 4321,
name: 'Education',
parentId: null,
children: [{
id: 1234,
name: 'category1',
parentId: 4321,
children: [{
id: 8327548,
name: '001',
parentId: 1234,
}, {
id: 8327549,
name: '002',
parentId: 1234,
}],
}, {
id: 6786,
name: 'Associations',
parentId: 4321,
}, {
id: 8262439,
name: 'category1',
parentId: 4321,
}, {
id: 8245,
name: 'Rights',
parentId: 4321,
children: [{
id: 2447,
name: 'Organizations',
parentId: 8245,
}, {
id: 9525,
name: 'Services',
parentId: 8245,
}, {
id: 8448,
name: 'Organizations',
parentId: 8245,
}],
}, {
id: 8262446,
name: 'Women\'s Rights',
parentId: 4321,
}],
}, {
id: 21610,
name: 'Agriculture',
parentId: null,
children: [{
id: 3302,
name: 'categoryABC',
parentId: 21610,
children: [{
id: 85379,
name: 'categoryABC - General',
parentId: 3302,
}, {
id: 85380,
name: 'categoryABC Technology',
parentId: 3302,
}],
}, {
id: 8303,
name: 'Fungicides',
parentId: 21610,
children: [{
id: 8503,
name: 'Fungicides - General',
parentId: 8303,
}],
}],
}];
console.log(response
.reduce(recursivelyReassambleAndCollectChildlessItems, { result: [] })
.result
)
.as-console-wrapper { min-height: 100%!important; top: 0; }
I have an array and I want to override the object attributes
This the main data
const Data = {
"id": "1",
"name": "USA",
"questions": [{ id: 1, name: "1 qst" }, { id: 2, name: "2 qst" }, { id: 3, name: "3 qst" }],
"children": [
{ "id": "1" , "name": "DC" ,"questions": [{ id: 1, name: "1 qst" }, { id: 2, name: "2 qst" }, { id:2, name: "3 qst" }]},
{ "id": "2" , "name": "Florida" ,"questions": [{ id: 1, name: "1 qst" }, { id: 2, name: "2 qst" }, { id: 3, name: "3 qst" }]}
]
}
I want to change in every question instead of name I want to put questionName like this
{ id: 1, questionName: "1 qst" }
I was able to change it in first object question through this code
let dataFiltred = Data[0]?.questions?.map((item) => {
return {
questionName: item.name,
id: item.id,
}
})
But I am struggling to change it in children question
function mapQuestionObject({ name, id }) {
return { id, questionName: name };
}
const mapped = {
...Data,
questions: Data.questions.map(mapQuestionObject),
children: Data.children.map(child => ({
...child,
questions: child.questions.map(mapQuestionObject),
}),
};
Map each questions array to a new array and change the name property in the mapped value.
const data = {
"id": "1",
"name": "USA",
"questions": [{ id: 1, name: "1 qst" }, { id: 2, name: "2 qst" }, { id: 3, name: "3 qst" }],
"children": [
{ "id": "1" , "name": "DC" ,"questions": [{ id: 1, name: "1 qst" }, { id: 2, name: "2 qst" }, { id:2, name: "3 qst" }]},
{ "id": "2" , "name": "Florida" ,"questions": [{ id: 1, name: "1 qst" }, { id: 2, name: "2 qst" }, { id: 3, name: "3 qst" }]}
]
};
const newData = {
...data,
questions: data.questions.map(({ name: questionName, ...rest }) => ({
...rest,
questionName,
})),
children: data.children.map(child => ({
...child,
questions: child.questions.map(({ name: questionName, ...rest }) => ({
...rest,
questionName,
}))
})),
};
console.log(newData);
Since the questions mapping is the same callback you can factor it out to make your code more DRY
const data = {
"id": "1",
"name": "USA",
"questions": [{ id: 1, name: "1 qst" }, { id: 2, name: "2 qst" }, { id: 3, name: "3 qst" }],
"children": [
{ "id": "1" , "name": "DC" ,"questions": [{ id: 1, name: "1 qst" }, { id: 2, name: "2 qst" }, { id:2, name: "3 qst" }]},
{ "id": "2" , "name": "Florida" ,"questions": [{ id: 1, name: "1 qst" }, { id: 2, name: "2 qst" }, { id: 3, name: "3 qst" }]}
]
};
const mapQuestions = arr => arr.map(({ name: questionName, ...rest }) => ({
...rest,
questionName,
}));
const newData = {
...data,
questions: mapQuestions(data.questions),
children: data.children.map(child => ({
...child,
questions: mapQuestions(child.questions),
})),
};
console.log(newData);
Suppose I have the following array of objects:
[
{ id: "1", categories: [ { category_id: "1"}, { category_id: "2"} ],
{ id: "2", categories: [ { category_id: "2"}, { category_id: "3"} ],
{ id: "3", categories: [ { category_id: "1"}, { category_id: "5"} ],
]
I want remove all the items which doesn't have as category_id those not included in this array of references: 1, 4, 5.
So the expected output should be: 1, 3, because the id 2 doesn't have any category id contained in teh references array.
I wrote this code:
items.filter(obj => !references.includes(obj.categories.category_id));
but this will return the same items
Expected result:
[
{ id: "1", categories: [ { category_id: "1"}, { category_id: "2"} ],
{ id: "3", categories: [ { category_id: "1"}, { category_id: "5"} ],
]
You could use Array#filter, Array#some and the value with Array#includes.
var array = [{ id: "1", categories: [{ category_id: "1" }, { category_id: "2" }] }, { id: "2", categories: [{ category_id: "2" }, { category_id: "3" }] }, { id: "3", categories: [{ category_id: "1" }, { category_id: "5" }] }],
keep = ["1", "4", "5"],
result = array.filter(({ categories }) =>
categories.some(({ category_id }) => keep.includes(category_id)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
obj.categories is an array, you have to iterate it in some way:
items.filter(obj => obj.categories.every(category => !references.includes(category.category_id)));
Here you have another approach that uses Array::findIndex()
const input = [
{id: "1", categories: [{category_id: "1"}, {category_id: "2"}]},
{id: "2", categories: [{category_id: "2"}, {category_id: "3"}]},
{id: "3", categories: [{category_id: "1"}, {category_id: "5"}]},
];
const references = [1, 4, 5];
let res = input.filter(
y => y.categories.findIndex(x => references.includes(Number(x.category_id))) >= 0
);
console.log(res);