Reputation: 671
The title probably isn't clear and I'm not sure how to articulate the idea without specifics so here's the rundown:
My code has an array of Players
(a class I wrote). I want to split the entries in the array evenly (based on their Players.rating
) between a given number of teams. The problem arises that the number of teams is a var teamAmount
and can be set between 2 and 8. I'm trying to find a simple way of creating a number of Player
class arrays equal to the value of teamAmount
(without having to write 7 switch cases). I was thinking a 2D array, but I can't think of how to initialize it. I feel like it could be simple, but I can't seem to work it out
Upvotes: 3
Views: 87
Reputation: 2843
here is an option for you:
// e.g. setting up Player(s)
struct Player {
var rating = 0
}
let players = [Player(rating: 1), Player(rating: 3), Player(rating: 2), Player(rating: 7), Player(rating: 5), Player(rating: 4), Player(rating: 3)]
let sortedPlayers = players.sort { $0.rating > $1.rating }
print(sortedPlayers)
// [Player(rating: 7), Player(rating: 5), Player(rating: 4), Player(rating: 3), Player(rating: 3), Player(rating: 2), Player(rating: 1)]
// e.g. setting up Team(s)
let numberOfTeams = 3
typealias Team = [Player]
// now do the work
let teams = sortedPlayers.enumerate().reduce(
Array(count: numberOfTeams, repeatedValue: Team()),
combine: { (var teams, let player) in
let (playerIndex, player) = player
teams[playerIndex % numberOfTeams].append(player)
return teams
}
)
print(teams)
// [[Player(rating: 7), Player(rating: 3), Player(rating: 1)], [Player(rating: 5), Player(rating: 3)], [Player(rating: 4), Player(rating: 2)]]
Upvotes: 1
Reputation: 6900
I've posted some pseudo-code below. You'll have to modify it to fit the Swift syntax (I'm away form a Mac at the moment and will edit this when I get home after I throw it in a playground.)
func generate2DArray(players: Array<Player>, numTeams: Int) -> Array<Array<String>>{
var teams = Array<Array<Player>>()
for index in 0...numTeams{
//init the first dimension of empty arrays for each team
teams.append([Player]())
}
for var i = 0; i < players.count; ++i{
//Place the player in the correct team respectively... (sorry about array syntax, I know its wrong)
teams[i % numTeams].append(players[i]);
}
return teams;
}
The basic idea is you know how many teams you want and you can init the first dimension of your 2D array with a simple for loop.
Then to place the players in the respective teams, just use the magical modulus.
Theory
(Since 4 % 4 is 0, you will have to offset your array, or provide some simple logic to cover that case, the easiest would be to have a team 0 instead of team 4)
Update
Just noticed you want them distributed evenly by the players rating. In that case, just make sure you sort the players by their rating before placing them into teams (I'll omit showing how to do that under the assumption that you know how to sort an array in Swift, comment if help is needed.)
Update
I tested the code I added and made some modifications so that it runs properly in Swift
Here are the results as expected
generate2DArray([player1, player2, player3, player4, player5, player6], 2)
//Returns [player1, player3, player5] , [player2, player4, player6]
generate2DArray([player1, player2, player3, player4, player5, player6], 4)
//Returns [player1, player5] , [player2, player6] , [player3] , [player4]
Upvotes: 1