Home > Back-end >  How to Filter a Nested Object with array of String
How to Filter a Nested Object with array of String

Time:11-18

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

CodePudding user response:

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

CodePudding user response:

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

CodePudding user response:

Maybe you're looking for something like this:

A simple recursive function can do the job.

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


const isObj = (val) => typeof val === 'object' && val !== null && !Array.isArray(val);

const findObj = (filters, obj) => {
  let resObject;
  for (const [k, v] of Object.entries(obj)) {
    if (typeof v === "string" && filters.some((item) => item === v)) {
      resObject = obj;
      break;
    } else if (isObj(v)) resObject = findObj(filters, obj[k]);
  }

  return resObject;
}

filters = ['Blue','2']; 

const res = products.find((product) => findObj(filters, product));
console.log(res);

  • Related