0

I have an array as following

array = [
{
  name: 'A'
  instructors: [
   {
     name:'InsA'
   }
  ]
  businessUnit: {name:'myBusiness'}
},
{
  name: 'B'
  instructors: [
   {
     name:'InsB'
   }
  ]
  businessUnit: {name:'myBusinessB'}
}

]

I want to filter this array with the values i have which are also in an array as following

classArr = [A,C,D]
instructorArr = [InsA,InsC,InsZ]
businessName = [myBusinessB,myBusinessX,myBusinessD]

NOTE: These filters can have empty arrays as well. For Ex: businessName = [] .

My current approach is to filter as follows

const filtered = array?.filter(
      (activity) =>
        classArr?.includes(activity.name) &&
        activity.instructors?.some((instructor) =>
          instructorArr?.some((instructorFilter) => instructor?.name === instructorFilter),
        ) &&
        businessName?.includes(activity.businessUnit?.name),
    );

But the issue is this returns if all conditions are met. Not when just 2 or 1 condition is met. How can i return the filtered array when several or all conditions are met?

3
  • 2
    did you try changing && to || in the filter function ? Commented Mar 31, 2021 at 11:41
  • 1
    I don't know if I understand the question correctly, but it appears that you want to use OR instead of AND Commented Mar 31, 2021 at 11:41
  • looks like Akif answer is sufficient Commented Mar 31, 2021 at 11:52

3 Answers 3

1
const filtered = array?.filter(
      (activity) =>
        classArr?.includes(activity.name) ||
        activity.instructors?.some((instructor) =>
          instructorArr?.some((instructorFilter) => instructor?.name === instructorFilter),
        ) ||
        businessName?.includes(activity.businessUnit?.name),
    );
Sign up to request clarification or add additional context in comments.

2 Comments

when i do this it does not return data with filter combination. Just data matching to individual filters
can you share an example of arrays and expected results?
0

In your filtered function

const filtered = array?.filter(
      (activity) =>
        classArr?.includes(activity.name) &&
        activity.instructors?.some((instructor) =>
          instructorArr?.some((instructorFilter) => instructor?.name === instructorFilter),
        ) &&
        businessName?.includes(activity.businessUnit?.name),
    );

You basically say you want to keep all activities where:
The array includes the class name
AND the array includes the instructor
AND the array includes the business unit
(the && operator is the AND operator).

However you state that you want to 'return the filtered array when several [OR] all conditions are met?'

So to fix this, you should switch out the && (AND) operator with the || (OR) operator like this:

const filtered = array?.filter(
      (activity) =>
        classArr?.includes(activity.name) ||
        activity.instructors?.some((instructor) =>
          instructorArr?.some((instructorFilter) => instructor?.name === instructorFilter),
        ) ||
        businessName?.includes(activity.businessUnit?.name),
    );

Comments

0

You need to check for the length in your array. Only doing array? with check if its nullish, not the size.

const filtered = array?.filter(
    (activity) =>
        (
            classArr.length ? classArr.includes(activity.name) : false 
        )
        && (
            activity.instructors.length  // check for length
                ? activity.instructors.some((instructor) => 
                    instructorArr.length  // check for length
                    ? instructorArr.some((instructorFilter) => instructor.name === instructorFilter)
                    : false) 
                : false
        ) 
        && (
            businessName.length ? businessName.includes(activity.businessUnit?.name) : false
        )
);

That line is very hard to read and will be hard for anyone else to understand in the future, so lets open it up

let filtered = [];
if (array.length){
    for (const index in myArray){
        const has_classArr = !!classArr.length;
        const has_instructorArr = !!instructorArr.length;
        const has_businessName = !!businessName.length; // check for length, if you do "businessName?" it only cheks for its existence

        if (has_classArr && has_instructorArr && has_businessName){
        
            const activity = myArray[index];
            const has_activityInstructors = activity.instructors && activity.instructors.length
            const has_activityBusinessUnit = !!activity.businessUnit

            if (has_activityInstructors && has_activityBusinessUnit){
                for (const instructor of activity.instructors){
                    if (instructorArr.includes(instructor.name) && businessName.includes(activity.buninessUnit.name) && classArr.includes(activity.name))
                        filtered.push(activity)
                }
            }
        }
    }
}

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.