2

I have an array with a nested array of objects, I want to filter the data where the object of the nested arrays meets multiple conditions.

Here's the sample data.

const providerList = [
  {
    id: "bac4ef8d",
    provider_name: 'Paa Ra'
    provider_gender: "Male",
    provider_item: [
      {
        itemID: "5911319b"
        is_approved: true,
        is_active: true,
      },
      {
        itemID: "937a56d7"
        is_approved: true,
        is_active: true,
      },
    ],
  },
  {
    id: "9df373d5",
    provider_name: "Che Ta",
    provider_gender: "Female",
    provider_item: [
      {
        itemID: "5911319b"
        is_approved: true,
        is_active: true,
      }
    ],
  }
]

These are the filters, note that the itemID can have any number of elements.

const itemFilter = {
  itemID: ["5911319b", "937a56d7"],
  is_approved: [true],
  is_active: [true],
};

Here's my code, however the output does not return as desired.

const filterProviders = providerList.filter(provider =>
  provider.provider_item.every(item =>
    Object.entries(itemFilter).every(([k, v]) => v.includes(item[k]))),
);

I require to filter the providerList and returning providers where the provier_item matches all values in itemFilter. The expected output for the above itemFilter would be:

filterProviders = [
  {
    id: "bac4ef8d",
    provider_name: 'Paa Ra'
    provider_gender: "Male",
    provider_item: [
      {
        itemID: "5911319b"
        is_approved: true,
        is_active: true,
      },
      {
        itemID: "937a56d7"
        is_approved: true,
        is_active: true,
      },
    ],
  }
]
4
  • Can you show the expected output? Commented Dec 21, 2021 at 18:45
  • do you want to have all itemID of nested provider_item or just some? Commented Dec 21, 2021 at 19:16
  • @jsejcksn I've updated to show the output. Commented Dec 22, 2021 at 6:12
  • @NinaScholz the return would require all, not some Commented Dec 22, 2021 at 6:14

1 Answer 1

1

Is this what you are after:

const providerList = [{
    id: "bac4ef8d",
    provider_name: 'Paa Ra',
    provider_gender: "Male",
    provider_item: [{
        itemID: "5911319b",
        is_approved: true,
        is_active: true,
      },
      {
        itemID: "937a56d7",
        is_approved: true,
        is_active: true,
      }
    ]
  },
  {
    id: "9df373d5",
    provider_name: "Che Ta",
    provider_gender: "Female",
    provider_item: [{
      itemID: "5911319b",
      is_approved: true,
      is_active: true,
    }],
  }
]

const itemFilter = {
  itemID: ["937a56d7", "5911319b"],
  is_approved: [true],
  is_active: [true],
}

const filterProviders = providerList.reduce((acc, provider) => {
  provider.provider_item = provider.provider_item.filter(item => (
    itemFilter.itemID.every(ai => provider.provider_item.map(i => i.itemID).includes(ai)) &&
    itemFilter.is_approved.includes(item.is_approved) &&
    itemFilter.is_active.includes(item.is_active)
  ))

  let providerCount = provider.provider_item.length

  if (providerCount > 0 && providerCount === itemFilter.itemID.length) {
    acc.push(provider)
  }

  return acc
}, [])

console.log(filterProviders)

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

4 Comments

Thanks, however, if I add another itemID to the itemFilter like itemID: ["937a56d7", "5911319b", the I get both results, however, I should get only provide with name 'Paa Ra'. The other user with name 'Che Ta' does not have both itemID so I should not return it
This important piece of information was missing at time of my posting. I have now updated my answer.
something's not adding up, for Provider 'Paa Ra', let's say we add a third provider_item where is_active and is_approved equates to true, and in the itemFilter the itemID is not chosen, then I still get the result for 'Paa Ra' which should not be the case, it should have returned null, because the itemFilter.itemID should match what's shown in the provider array
In that case, you can additionaly check to see if filtered providerList has the same number of providers as the filter. I have updated my answer again.

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.