Is there a way to use less code to filter an array and transform it ready for a SWAL select?

Viewed 49

Say you have:

this.group.players = [{id:1,name:'Joe Bloggs'},
                      {id:2,name:'Jane Bloggs'},
                       ...
                      ];

Now say you have list of all players (loaded via ajax):

newPlayers = [0:{id:1,name:'Joe Bloggs'},
              1:{id:2,name:'Jane Bloggs'},
              2:{id:3,name:'Jeffery Bloggs'},
              3:{id:4,name:'Jared Bloggs'},
              ...
              ];

The user wants to add a new player to this.group.players, so I'm showing them a select (using SWAL), which takes the data in the form of value:name. I want to skip the players that are already in this.group.players. So I want to end up with this:

selectOptions = [3:'Jeffery Bloggs',
                 4:'Jared Bloggs',
                 ...
                ];

Here's the code I'm using to achieve this just now:

  let playerIDs = this.group.players.map((player)=>{ return parseInt(player.id); });

  axios.get(route('player.index'))
       .then(async (response)=>{
               let selectOptions = response.data.reduce((result,player)=> {
                  if (playerIDs.includes(player.id)) { return result; }
                  result[player.id] = player.name;
                  return result;
               },{});
        })
        .catch( ...

This feels like it could be considerably improved? Any suggestions?

1 Answers

You could first filter the player ids and then map the player names and ids, this would give you an array with the players names and ids:

response.data
    .filter(({id})=> playerIDs.includes(id))
    .map(({id, name}) => {id, name})

You could also easily sort it by ids if you want :

response.data
    .filter(({id})=> playerIDs.includes(id))
    .map(({id, name}) => {id, name})
    .sort((player1, player2) => player1.id - player2.id)

Finally, if you want the exact format you describe in your question, that is an object with ids as keys and names as values, I believe you would have to use reduce and end up with a bit more verbose function :

response.data
    .filter(({id})=> playerIDs.includes(id))
    .reduce((players, player) => ({...players, [player.id]: player.name}), {})
Related