Home > Software design >  Is there any way to filter objects from array of objects that should include all selected values in
Is there any way to filter objects from array of objects that should include all selected values in

Time:09-03

Here i have skills array and employees array and i am trying to get the employees that includes all the skills that are included in skills array using reduce, filter or find method. I am trying to stored the filtered employees in filteredItems but got stuck in it.

filteredItems = Skills?.length>0   ?             
Employees?.filter((item) => {
return     item.Skills.find((ele) => {
                  return Skills.find((el) => {
                    if(el.value === ele.id){
                       return ele
                    }
                  })
            })
          }) : []

Below are the arrays mentioned.

Skills Array

[
{
    "value": 6,
    "label": "Marketing"
},
{
    "value": 20,
    "label": "Golang"
}
]

Employees Array

[
{
    "name": "Hassan",
    "id": 56,
    "Skills": [
        {
            "id": 20,
            "name": "Golang",
        },
    ],
},
 {
    "name": "Haroon",
    "id": 95,
    "Skills": [
        {
            "id": 6,
            "name": "Marketing",
        },
        {
            "id": 20,
            "name": "Golang",
        },
    ],
},
]

For example, in above scenario of arrays it should return employee of id of 95 not return employee of id 56 because it includes skills but not all that are mention in skills array.

CodePudding user response:

You could create another property in the employees array.. call it "QUalified". Default it to true, then set it to false when the employee doesn't have a skill in the skills array.

let arSkills = [
{
    "value": 6,
    "label": "Marketing"
},
{
    "value": 20,
    "label": "Golang"
}
];

let arEmp = [
{
    "name": "Hassan",
    "id": 56,
    "Skills": [
        {
            "id": 20,
            "name": "Golang",
        },
    ],
},
 {
    "name": "Haroon",
    "id": 95,
    "Skills": [
        {
            "id": 6,
            "name": "Marketing",
        },
        {
            "id": 20,
            "name": "Golang",
        },
    ],
},
];

arEmp.forEach(ele =>{
    ele.Qualified = true;
  let arTmp = [];
  
  for(let {id} of ele.Skills)
    arTmp.push(id)
  
  for(let {value} of arSkills)
    if(!arTmp.includes(value))
        ele.Qualified = false
});

let arQual = arEmp.filter((ele) =>{
    return ele.Qualified
});

console.log(arQual);

CodePudding user response:

I found it easier to first encapsulate an array of skill IDs to search for.

let skillIds = Skills.map(s => s.value);

Then I filtered and compared the end result to the length of the skill Ids array:

let filteredItems = Skills?.length > 0 ?
  Employees?.filter(item => item.Skills.filter( s =>
      skillIds.includes(s.id)).length==skillIds.length): []

let Skills = [{
  "value": 6,
  "label": "Marketing"
}, {
  "value": 20,
  "label": "Golang"
}]
let Employees = [{
  "name": "Hassan",
  "id": 56,
  "Skills": [{
    "id": 20,
    "name": "Golang",
  }],
}, {
  "name": "Haroon",
  "id": 95,
  "Skills": [{
      "id": 6,
      "name": "Marketing",
    },
    {
      "id": 20,
      "name": "Golang",
    },
  ],
}, ]

let skillIds = Skills.map(s => s.value);

let filteredItems = Skills?.length > 0 ?
  Employees?.filter(item => item.Skills.filter( s => skillIds.includes(s.id)).length==skillIds.length): []

console.log(filteredItems)

  • Related