0

I have an array with names

const players = ['name1','name2','name3','name4','name5','name6','name7','name8'];

const teams = players.length / 2; // -> 4 teams

I want to make teams of 2 people (randomly chosen) and make new arrays from the results -> team

function createTeams() {
  for (let i = 0; i < teams; i++) {
    for (let x = 0; x < 2; x++) {
      // get a random player
      selectedPlayer = players[Math.floor(Math.random() * players.length)];
      console.log('Selected Player will be added to a team: ', selectedPlayer);

      // delete this player from the array
      while (players.indexOf(selectedPlayer) !== -1) {
        players.splice(players.indexOf(selectedPlayer), 1);
      }

      // add this player to a new array
      //?????
    }
  }
}

Anyone knows how to do this?

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
saerts
  • 17
  • 3
  • 2
    Looks like an overly complicated approach to me. Shuffle your array, and then divide it into chunks using https://stackoverflow.com/q/8495687/1427878 – CBroe Jul 13 '22 at 09:01
  • Wow, I tested them all out, and they are all valid solutions ... I don't know which I like the most :) Thank you so much!!! – saerts Jul 13 '22 at 16:00

6 Answers6

0

You can define a new Array which will contains the teams where you push the two players.

Note that it's better to pass the players array as a parameters of the function and make a swallow copy of it so it won't modify the player array.

const players = ['name1','name2','name3','name4','name5','name6','name7','name8'];

function createTeams(players) {
  const playersLeft = [...players]
  const newTeams = []  
  const nbTeams = players.length / 2
  for (let i=0; i<nbTeams; i++){
    const player1 = playersLeft.splice(Math.floor(Math.random()*playersLeft.length),1)[0]
    const player2 = playersLeft.splice(Math.floor(Math.random()*playersLeft.length),1)[0]
    
    newTeams.push([player1, player2])
  }
  
  return newTeams
}

console.log(createTeams(players))

Edit : Improve version using a nbPlayerPerTeam parameter

const players = ['name1', 'name2', 'name3', 'name4', 'name5', 'name6', 'name7', 'name8'];

function createTeams(players, nbPlayerPerTeam) {
  const playersLeft = [...players]
  const newTeams = []
  const nbTeams = players.length / nbPlayerPerTeam
  for (let i = 0; i < nbTeams; i++) {
    const players = []
    for (let j = 0; j < nbPlayerPerTeam; j++) {
      const player = playersLeft.splice(Math.floor(Math.random() * playersLeft.length), 1)[0]

      players.push(player)

    }


    newTeams.push(players)
  }

  return newTeams
}

console.log(createTeams(players, 3))
RenaudC5
  • 3,553
  • 1
  • 11
  • 29
0
function pickTeams(array, teamSize) {

  // Shuffle array, make a copy to not alter original our original array
  const shuffled = [...array].sort( () => 0.5 - Math.random());

  const teams = [];
  // Create teams according to a team size
  for (let i = 0; i < shuffled.length; i += teamSize) {
    const chunk = shuffled.slice(i, i + teamSize);
    teams.push(chunk);
  }
  
  return teams;
  
}

const players = ['name1','name2','name3','name4','name5','name6','name7','name8'];

const teams = pickTeams(players, 2);
munleashed
  • 1,677
  • 1
  • 3
  • 9
  • The shuffle implementation is not valid. It is error prone for it relies on random return values which violates the rule(s) for a [stable sorting algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description). – Peter Seliger Jul 13 '22 at 17:44
0

const players = ['name1', 'name2', 'name3', 'name4', 'name5', 'name6', 'name7', 'name8'];

// Divide data by length
const divide = (arr, n) => arr.reduce((r, e, i) =>
  (i % n ? r[r.length - 1].push(e) : r.push([e])) && r, []);

const shuffle = (arr) => {
  // Deep copy an array using structuredClone
  const array = structuredClone(arr);
  let currentIndex = array.length, randomIndex;
  // While there remain elements to shuffle
  while (currentIndex != 0) {
    // Pick a remaining element
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;
    // And swap it with the current element
    [array[currentIndex], array[randomIndex]] = [
      array[randomIndex], array[currentIndex]
    ];
  }
  return array;
}

// Shuffle players
const shuffled = shuffle(players);

// Set a number of people in a team
const groups = divide(shuffled, players.length / 2);

groups.forEach((team, i) => console.log(`team ${i+1}`, JSON.stringify(team)));
Ian
  • 1,198
  • 1
  • 5
  • 15
0

Check this updated code, I hope it will work for you. Just create two dimensional array and push players.

    const players = ['name1','name2','name3','name4','name5','name6','name7','name8'];
    let multi_team=new Array;     // new array for team of random 2 players
    const teams = players.length / 2; // -> 4 teams
    console.log(teams);
    createTeams();
    function createTeams() {
        for (let i = 0; i < teams; i++) {
            multi_team[i]= new Array;
            for (let x = 0; x < 2; x++) {
                // get a random player
                selectedPlayer = players[Math.floor(Math.random() * players.length)];
                multi_team[i][x]=selectedPlayer;
                 // delete this player from the array
                while (players.indexOf(selectedPlayer) !== -1) {
                    players.splice(players.indexOf(selectedPlayer), 1);
                }

            }
        }
        console.log(multi_team);
    }
Waqas Altaf
  • 392
  • 3
  • 16
0

To differ from previous answers, this is a dynamic way to do it, so you don't care if there are 5 teams or 2, 10 players or 500.

const players = ['j1', 'j2', 'j3', 'j4', 'j5', 'j6', 'j7', 'j8'];

const organizeTeams = (numberOfTeams, players) => {
  var teams = [];
  // Clone the array to avoid mutations
  const freePlayers = [...players];
  // How many players will play per team
  const playersPerTeam = Math.floor(players.length / numberOfTeams);
  // How many player won't have team
  const unorganizablePlayers = freePlayers.length % numberOfTeams;

  for (let t = 1; t <= numberOfTeams; t++) {
    teams = [...teams, pickRandomPlayers(freePlayers, playersPerTeam)];
  }

  return { teams, playersPerTeam, unorganizablePlayers };
};

const pickRandomPlayers = (players, playersPerTeam) => {
  let pickedPlayers = [];

  for (let c = 1; c <= playersPerTeam; c++) {
    const index = Math.floor(Math.random() * (players.length - 1));
    const player = players[index];

    pickedPlayers = [...pickedPlayers, player];

    // When we pick the player we remove it from the array to avoid duplicates.
    players.splice(index, 1);
  }

  return pickedPlayers;
};

const championship = organizeTeams(3, players);

console.log(`We have ${championship.teams.length} teams.`);
championship.teams.forEach((team, index) => {
  console.log(`Team ${index + 1} players: ${team.join(',')}`);
});
console.log(
  `There was no place to assign ${championship.unorganizablePlayers} players`
);
Osakr
  • 1,027
  • 1
  • 13
  • 26
0

The OP needs (to implement ) a reliable shuffle and likewise an array's chunk functionality.

Then one just has to shuffle the provided players array (or a shallow copy of the latter) and to divide the array of randomly ordered player items into chunks, each of custom provided length.

function shuffleArray(arr) {
  let idx;
  let count = arr.length;

  while (--count) {
    idx = Math.floor(Math.random() * (count + 1));
    [arr[idx], arr[count]] = [arr[count], arr[idx]];
  }
  return arr;
}

function createListOfChunkLists(arr, chunkLength = 0) {
  chunkLength = Math.max(0, chunkLength);

  return (chunkLength === 0 && []) ||
    arr.reduce((list, item, idx) => {
      if (idx % chunkLength === 0) {

        list.push([ item ]);
      } else {
        list[list.length - 1].push(item);
 
        // `at` still not supported by safari.
        // list.at(-1).push(item);
      }
      return list;
    }, []);
}

// ... OP ... I have an array with names
const players = ['name1', 'name2', 'name3', 'name4', 'name5', 'name6', 'name7', 'name8'];

// ... OP ... I want to make teams of 2 people (randomly chosen)
//            and make new arrays from the results -> team
const teams = createListOfChunkLists(
  shuffleArray([...players]), 2
);
console.log({ teams, players });

console.log({
  teams: createListOfChunkLists(
    shuffleArray([...players]), 2
  ),
  players
});
console.log({
  teams: createListOfChunkLists(
    shuffleArray([...players]), 4
  ),
  players
});
.as-console-wrapper { min-height: 100%!important; top: 0; }
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37