Reputation: 49
Sample code.
const cards = [
{
id: "1",
name: "J",
tag: [
{
"colour": "red"
},
{
"colour": "yello"
},
{
"colour": "blue"
},
{
"colour": "white"
},
],
size: [
{
"name": "small"
},
{
"name": "medium"
},
],
},
{
id: "2",
name: "S",
tag: [
{
"colour": "red"
},
{
"colour": "green"
},
{
"colour": "black"
},
],
size: [
{
"name": "small"
},
{
"name": "medium"
},
],
},
{
id: "3",
name: "K",
tag: [
{
"colour": "green"
},
{
"colour": "purple"
},
{
"colour": "brown"
},
{
"colour": "white"
},
],
size: [
{
"name": "large"
},
],
}
];
Test arrays
const sizeArray = ["medium", "small"];
const tagArray = ["red", "black"];
I want the filtered array of objects to only include the second object in this example. Filtering only those who match all criteria leaving me with a new array of objects.
I've tried with .filter, .some, .includes and no luck looking over many other answers to similar questions.
Thanks a lot.
Upvotes: 0
Views: 63
Reputation: 25408
You can use the filter with every and some.
Since you need to filter the result which contains all sizeArray
and tagArray
in size
and tag
array respectively.
const cards = [
{
id: "1",
name: "J",
tag: [
{
colour: "red",
},
{
colour: "yello",
},
{
colour: "blue",
},
{
colour: "white",
},
],
size: [
{
name: "small",
},
{
name: "medium",
},
],
},
{
id: "2",
name: "S",
tag: [
{
colour: "red",
},
{
colour: "green",
},
{
colour: "black",
},
],
size: [
{
name: "small",
},
{
name: "medium",
},
],
},
{
id: "3",
name: "K",
tag: [
{
colour: "green",
},
{
colour: "purple",
},
{
colour: "brown",
},
{
colour: "white",
},
],
size: [
{
name: "large",
},
],
},
];
const sizeArray = ["medium", "small"];
const tagArray = ["red", "black"];
const result = cards.filter(({ tag, size }) =>
sizeArray.every((s) => size.some((si) => si.name === s)) &&
tagArray.every((t) => tag.some((ta) => ta.colour === t))
);
console.log(result);
Upvotes: 3
Reputation: 16576
As you filter
the main array, you want to make sure at least one of the tag
values is in the tagArray
and at least one of the size
values is in the sizeArray
. This can be achieved using includes
.
const cards=[{id:"1",name:"J",tag:[{colour:"red"},{colour:"yello"},{colour:"blue"},{colour:"white"}],size:[{name:"small"},{name:"medium"}]},{id:"2",name:"S",tag:[{colour:"red"},{colour:"green"},{colour:"black"}],size:[{name:"small"},{name:"medium"}]},{id:"3",name:"K",tag:[{colour:"green"},{colour:"purple"},{colour:"brown"},{colour:"white"}],size:[{name:"large"}]}];
const sizeArray = ["medium", "small"];
const tagArray = ["red", "black"];
const filtered = cards.filter((card) => {
return (
card.tag.some((tag) => tagArray.includes(tag.colour)) &&
card.size.some((size) => sizeArray.includes(size.name))
);
});
console.log(filtered);
Note that includes
isn't super efficient, but I'm assuming you're not working with tons of data here. If your sizeArray
or tagArray
are especially large, you could look into something like the Set
object for hash table efficiency.
Upvotes: 2