Reputation: 41
let products = [
{
name: "A",
color: "Blue",
size: {
size1: 1,
size2: 2,
size3: 3,
},
},
{
name: "B",
color: "Blue",
size: {
size1: 5,
size2: 19,
size3: 22,
},
},
{ name: "C", color: "Black", size: 70 },
{ name: "D", color: "Green", size: 50 },
];
filters = ['Blue','2'];
the result must be the object that checks all strings in the array for example
{
name: "A",
color: "Blue",
size: {
size1: 1,
size2: 2,
size3: 3,
},
},
the research must be accepted whatever the value in the
Upvotes: 2
Views: 492
Reputation: 8087
The function strings
returns all nested strings within an object, converting any numbers to strings. Then, we just filter any product where the list of strings includes all necessary matches.
const products = [{"name":"A","color":"Blue","size":{"size1":1,"size2":2,"size3":3}},{"name":"B","color":"Blue","size":{"size1":5,"size2":19,"size3":22}},{"name":"C","color":"Black","size":70},{"name":"D","color":"Green","size":50}];
const filters = ['Blue','2'];
const subsetMatch=(a,s)=>s.every(i=>a.includes(i));
const strings=i=>typeof i==='object'?Object.values(i).flatMap(strings):i+'';
console.log(products.filter(i=>subsetMatch(strings(i),filters)));
Upvotes: 0
Reputation: 386540
You could take a closure over any of the search values and check if all of them are in the object or nested objest for filtering.
const
has = f => {
const check = o => o && typeof o === 'object'
? Object.values(o).some(check)
: f === o;
return check;
},
products = [{ name: "A", color: "Blue", size: { size1: 1, size2: 2, size3: 3 } }, { name: "B", color: "Blue", size: { size1: 5, size2: 19, size3: 22 } }, { name: "C", color: "Black", size: 70 }, { name: "D", color: "Green", size: 50 }],
search = ['Blue', 2],
result = products.filter(o => search.every(f => has(f)(o)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 76426
You can resolve the nest via using a stack in some manner, either by recursion or iteratively using a stack explicitly. Here's a recursive solution:
function getFiltered(obj, filters, found = null) {
let outermostCall = (found === null);
if (outermostCall) { //outermost call
found = [];
for (let index = 0; index < filters.length; index++) {
found[index] = false;
}
}
for (let key in obj) {
if (typeof obj[key] === 'object') {
let tempFound = getFiltered(obj[key], filters, found);
for (let index = 0; index < found.length; index++) {
if (tempFound[index]) found[index] = true;
}
} else {
let foundIndex = -1;
for (let index = 0; index < filters.length; index++) {
if (filters[index] == obj[key]) {
foundIndex = index;
index = filters.length;
}
}
if (foundIndex >= 0) {
found[foundIndex] = true;
}
}
}
if (outermostCall) {
return !found.filter(item => !item).length;
}
return found;
}
function getAllFiltered(array, filters) {
let output = [];
for (let obj of array) {
if (getFiltered(obj, filters)) output.push(obj);
}
return output;
}
let products = [
{
name: "A",
color: "Blue",
size: {
size1: 1,
size2: 2,
size3: 3,
},
},
{
name: "B",
color: "Blue",
size: {
size1: 5,
size2: 19,
size3: 22,
},
},
{ name: "C", color: "Black", size: 70 },
{ name: "D", color: "Green", size: 50 },
];
let filters = ['Blue','2'];
console.log(getAllFiltered(products, filters));
Upvotes: 1
Reputation: 177
You can use Array.every
to check if all the filters are present in the object, if that's what you mean.
const products = [
{ name: "A", color: "Blue", size: { size1:1, size2:2, size3:3 } },
{ name: "B", color: "Blue", size: { size1:5, size2:19, size3:22 } },
{ name: "C", color: "Black", size: 70 },
{ name: "D", color: "Green", size: 50 },
];
const filters = ['Blue','2'];
const filtered = products.filter(product => {
return Object.values(product).every(value => {
return filters.includes(value);
});
});
console.log(filtered);
Upvotes: 0