1

What's the best way to return data from an array if the index matches another array?

I have a collection of users:

Collection [Map] {
 '531592097837613058' => {}
 '460281004972572672' => {}
}

And I have array with allowed IDs:

const allowedRoles = ['523928765865394211'];

What I'd like to achieve, is return collection's object where the index matches some one of the indexs in AllowedRoles. In theory, it's quite simple, but I'm misunderstanding collection methods.

webmasterdro
  • 224
  • 2
  • 10
  • 1
    use `map` for this, over your `allowedRoles` array and use `filter` on your user collection. – Bibberty May 22 '19 at 21:56
  • 2
    Start by describing **in words** each step to do this. Be as detailed as you can. – Code-Apprentice May 22 '19 at 21:58
  • Possible duplicate of [filtering an array of objects based on another array in javascript](https://stackoverflow.com/questions/46894352/filtering-an-array-of-objects-based-on-another-array-in-javascript) – Heretic Monkey May 22 '19 at 22:09

3 Answers3

0

If you have a map of users (ie userMap), and an array of allowedRoles that you want to filter users by, then a simple way to obtain this a new collection of users would be to:

  1. Iterate the key/value entries of the userMap and
  2. If the current entry key is present in the allowedRoles array, include the user value in the resulting array

This can be expressed as:

const userMap = {
 '531592097837613058' : { user : "bob" },
 '460281004972572672' : { user : "bill" },
 '124' : { user : "joe" },
 '523928765865394211' : { user : "sam" }
}

const allowedRoles = ['523928765865394211', '124'];


const allowedUsers = [];

/* Iterate entries of user map */
for(const [key, value] of Object.entries(userMap)) {
  
  /* If key of user map present in allowed roles, add the value (user)
  to allowed users */
  if(allowedRoles.indexOf(key) !== -1) {
    allowedUsers.push(value);
  }
}

console.log(allowedUsers);
Dacre Denny
  • 29,664
  • 5
  • 45
  • 65
0

Assuming users is your dictionary/map of user ids, there are two ways to accomplish what you want:

// The functional way    
result = allowedRoles.map(id => users[id]).filter(userData => userData != undefined)

// With loops
result = []
for(id of allowedRoles) {
    if(users[id] != undefined) result.push(users[id])
}
KoreanwGlasses
  • 284
  • 1
  • 7
0

If you know that all the ids in allowedRoles exist in the Collection, you can just map over allowedRoles and do the lookup. If it's possible other ids exist in allowedRoles filter them out first:

let Collection = new Map ([
  ['531592097837613058', {name: "Fred"}],
  ['523928765865394211', {name: "Barney"}]
]);
 
 const allowedRoles = ['523928765865394211'];

 let roles = allowedRoles
             //.filter(item => Collection.has(item)) // if you need it
             .map(item => Collection.get(item))

 console.log(roles)

Because Map lookups are constant time, this should be O(n) where n is the length of allowedRoles

Mark
  • 90,562
  • 7
  • 108
  • 148