2
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

8
  • What does it mean by '2' here filters = ['Blue','2'] ? Commented Nov 18, 2022 at 12:40
  • Why aren't you using an array for the size property: size: [1,2,3]? Commented Nov 18, 2022 at 12:43
  • @Asraf it's the same principle as in Excel, I have an input and whatever values are written by the User, must be displayed all the objects that match these values, in combination Commented Nov 18, 2022 at 12:45
  • @adiga the array presents the inputs added by the User, the length can be varied Commented Nov 18, 2022 at 12:46
  • @kb9 that means it only matches string(s) of an object? Commented Nov 18, 2022 at 12:48

4 Answers 4

1

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));

Sign up to request clarification or add additional context in comments.

Comments

1

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; }

Comments

0

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);

Comments

0

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)));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.