0

I have multiple user profiles similar to below...

"user": {
    "firstName": "Joe",
    "lastName": "Bloggs",
    "userRole": [
            {
                "id": 1,
                "name": "Role 001",
            },
            {
                "id": 2,
                "name": "Role 002",
            },
           { etc... }
        ],
}

Each user may have a combination of different roles. I need to filter my users based on a comma delimited string for example {"Role 001", "Role 004"}... something like having a field containing a list of roles and using the includes function, but for an array.

My component...

<Signoff
    name="sign"
    signOff={signOff}
    signUserRole={["Role 001","Role 004"]} <--- my comma delimited string param. Not sure if I'm defining this correctly.
    signHeaderTitle="Person signature required"
/>

My user schema...

const userSchema = new Schema(
  {
    firstName: { type: String, required: true },
    lastName: { type: String, required: true },
    userRole: [
      {
        id: { type: Number },
        name: { type: String },
      },
    ],
  },
  { _id: true, timestamps: true }
);

My filter criteria based on a single select MUIAutocomplete dropdown which works perfectly...

setSigneeOptions(
              responseData.users

                .filter((value) =>
                  value?.userRole?.name === signUserRole // trying to do something like this --> value?.userRole?.name.including(signUserRole)
                    : 1 === 1
                )

                .sort((a, b) => (a.name > b.name ? 1 : -1))
            )

I need my MUIAutocomplete to be a multi select and am lost on how to filter its option set to include only the roles as defined in my comma separated string. {"Role 001", "Role 004"}. I hope I'm making sense. Any pointers appreciated.

  • Do you want to filter users with at least one of signUserRoles or all signUserRoles? – Ever Dev May 31 '23 at 09:00
  • A user can have multiple roles of any combination. I need to return all users with one or more comma delimited role names. So if a user has say Role 001, Role 005, Role 008 assigned to them and other users have same and other roles...and my criteria is that I want all users that have say Role 005 and Role 008 to be in n my option set... Hope that helps. I'll try implement the suggestions put forward in the morning. Thanks for your help. – Steven Davisworth May 31 '23 at 14:33

2 Answers2

0

You can filter users by

responseData.users?
  .filter((user) =>
    // you can use `.every()` to filter users with all signUserRole,
    // `.some()` to filter users with any of signUserRole 
    signUserRole.every(role => 
      user.userRole.find((userRole) => userRole.name === role)
    )
  )
  .sort((a, b) => (a.name > b.name ? 1 : -1))
Ever Dev
  • 1,882
  • 2
  • 14
  • 34
0

O(n2) solution looks like below:

responseData.users
    .filter((value) => signUserRole.includes(value?.userRole?.name))
    .sort((a, b) => (a.name > b.name ? 1 : -1))

But a better O(n) solution would be convert signUserRole to Set instead of an Array and have the logic like below:

responseData.users
    .filter((value) => signUserRole.has(value?.userRole?.name))
    .sort((a, b) => (a.name > b.name ? 1 : -1))
Santosh
  • 61
  • 2
  • 7