-1

I'm creating a google chrome extension that will use some data that are stored inside a JSON file. I need to compose a team of 11 members that needs to be extracted from the processed JSON file, but I don't know how to proceed. After I've parsed the file, I want that for every team position there are only x team members. For example, I need to randomly select one Goalkeeper, three, four or five defenders, three four or five midfield and one, two or three attackers. With PHP I'm able to do that without problems, but I'm not very experienced with javascript and I need help. Is there any function or any way to achieve this?

JSON

{
"player_id":3,
"player_surname":"Immobile",
"player_name":"Ciro",
"player_number":17,
"team_name":"Lazio",
"team_abbreviation":"LAZ",
"role_abbreviation":"A",
"role_name":"Attaccante",
"quotation":62,
}

JS

const uri = 'api/players_.json';
$.getJSON(uri, function(data){
 // code stuff here
});
jihuuNI
  • 551
  • 2
  • 5
  • 17
  • 1
    Could you add an example of the JSON object to your question? This way we can help with retrieving various data. – MaartenDev Sep 01 '19 at 17:35
  • @MaartenDev I've updated the question with the representation of a single player from the JSON file. It contains all the players of the Italian Serie A for a total of 588 entries. – jihuuNI Sep 01 '19 at 17:45
  • I would take a look at [Array.prototype.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), [Array.prototype.splice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice), and [Math.random](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random). You could also post your php code and someone could tell if the same approach is valid in JavaScript – Iván Nokonoko Sep 01 '19 at 18:04
  • @IvánNokonoko I didn't wrote `PHP` code for this project because it's a chome extension so it would be a waste of time due to the difference from JS and php – jihuuNI Sep 01 '19 at 18:22

1 Answers1

1

A combination of reduce, map and filter can be used to setup teams:

    const players = [
        {
            "player_id":3,
            "player_surname":"Immobile",
            "player_name":"Ciro",
            "player_number":17,
            "team_name":"Lazio",
            "team_abbreviation":"LAZ",
            "role_abbreviation":"A",
            "role_name":"Attaccante",
            "quotation":62,
        },
        {
            "player_id":3,
            "player_surname":"Immobile",
            "player_name":"Ciro",
            "player_number":17,
            "team_name":"Lazio",
            "team_abbreviation":"BLAA",
            "role_abbreviation":"A",
            "role_name":"Attaccante",
            "quotation":62,
        }
    ];


    const playersPerTeam = Object.values(players.reduce((acc, player) => {
        const teamKey = player.team_abbreviation;

        if(!acc.hasOwnProperty(teamKey)){
            acc[teamKey] = [];
        }

        acc[teamKey].push(player);
        return acc;
    }, {}));

    const chosenSetupPerTeam = playersPerTeam.map(playersInTeam => {
        const playersNeededPerRole = {
            "Portiere": 1, // Keeper
            "Difensore": 4, // Defender
            "Centrocampista": 4, // midfielder
            "Aggressore": 2, // Attacker
        };

        const playersPresentPerRole = {};

        // Get a team to fulfil the requirements stated in playersNeededPerRole
        return playersInTeam.filter(player => {
            // Role does not exist, thus the player can't join the team
            if(!playersNeededPerRole.hasOwnProperty(player.role_name)){
                return false;
            }
            // Set the default of players present per role to 0
            if(!playersPresentPerRole.hasOwnProperty(player.role_name)){
                playersPresentPerRole[player.role_name] = 0;
            }
            // Stop if all positions have been filled as specified in playersNeededPerRole
            if(playersPresentPerRole[player.role_name] === playersNeededPerRole[player.role_name]){
                return false;
            }

            playersPresentPerRole[player.role_name]++;

            return true;
        });
    });

    console.log(chosenSetupPerTeam)

Checkout the demo

jihuuNI
  • 551
  • 2
  • 5
  • 17
MaartenDev
  • 5,631
  • 5
  • 21
  • 33
  • I will try your code in my IDE. can you explain in depth what it will do and how? I see the comments in the code, but from the demo it's not clear what's happen – jihuuNI Sep 01 '19 at 18:26
  • First it groups all players by their team, this way we know which players can play with each other. Then we loop through all the teams and find 11 possible players. To find 11 possible players we loop through all the players in the team. For each player we check if their role `role_name` is needed in the setup(`playersNeededPerRole`) and isn't already fulfilled(`playersPresentPerRole`). If there is space left for the player the player is left in the team otherwise it gets left out. Filtering the players is done using `.filter`, if the callback returns true the player stays. @jihuuNI – MaartenDev Sep 01 '19 at 18:33
  • The `console.log` outputs the 11 chosen players per team. You can combine this code with the `getJson` call and get 11 chosen players per team. @jihuuNI – MaartenDev Sep 01 '19 at 18:35
  • Ok thank you for the explainations. The approach you've suggested to me is perfect, but If I want to get the players indipendently from their appartenence team and create a team is it possible with some code modification? – jihuuNI Sep 01 '19 at 20:37
  • If not sure what you mean with appartenence? With fields should be used. @jihuuNI – MaartenDev Sep 02 '19 at 07:24
  • I mean that it's not necessary to group players by their team to know which players can play with each other, it's more useful if the composed teams are random. – jihuuNI Sep 02 '19 at 10:58
  • So any player can play in any group of 11? @jihuuNI – MaartenDev Sep 02 '19 at 11:23
  • Yes @MaartenDev – jihuuNI Sep 02 '19 at 11:34
  • But what will the endresult be? One team of 11? or totalplayers/11 amount of teams? @jihuuNI – MaartenDev Sep 02 '19 at 13:32
  • I Just want one team, I want to use the result ream to suggest an ideal team for the next match day of the italian serie A, the team it's for the fantacalcio. For now I'm not planning to simulate a match between two teams. so endresult will be a team of 11 player from all the players available @MaartenDev – jihuuNI Sep 02 '19 at 14:38
  • I'm testing your code, I've implemented it using standard `function(var)` instead of promises `functionName => (var)`, I've noticed that the console is logging an array of 20 subarrays that will contain the players for every team. Is this the beahviour that the code is supposed to log in the consolle? How I can restrict it to only one array? @MaartenDev – jihuuNI Sep 02 '19 at 15:04
  • I've also noticed that the players extracted are always the same? @MaartenDev – jihuuNI Sep 02 '19 at 15:18
  • The following statements: `function(var)` and `functionName => (var)` are both functions not promises. The latter one is a so called [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). And the 20 subarrays is the expected behaviour, to randomize the teams you would have to shuffle the player array you receive from the API. @jihuuNI – MaartenDev Sep 02 '19 at 17:49
  • ok, I was thinking that the teams were randomly extracted from the json file provided by the api. I will look on SO for a way to randomize the input array data, but it's already in a random order, the players are not grouped by teams like the function does, but by players roles. Any suggestion is appreciated – jihuuNI Sep 02 '19 at 17:57
  • There are a lot of solutions out there on SO that help with randomizing data,this would be a good step for setup up teams. @jihuuNI – MaartenDev Sep 02 '19 at 18:20
  • 1
    Yes, I'm thinking to use the `Math.random()` after the players are divided by appartenence team and then setup teams with a random index value for every player. I will try to implemnt this on the code you've provoded @MaartenDev – jihuuNI Sep 02 '19 at 18:25