使用LINQ(灯具列表)形成锦标赛表

我有一系列的玩家(字符串[]),现在我需要得到一组代表游戏(playerN-playerM)的对象来组织锦标赛表,如下图所示: 在此处输入图像描述

期望的最终结果是生成具有需要播放的所有游戏的夹具列表。

如何以高效的方式使用LINQ?

更新:AB,AC,AD不正确 – 游戏应该能够并行运行。 我需要的结果与图片中的顺序相同

以下代码可用于为一组球队生成一个夹具列表,以确保每次在1个主场和1个客场比赛中比赛所有其他球队。

代码有点长,但它确实可以通过按照您指定的顺序为您提供列表。

代码可能会被优化,但目前这是我的头脑。

注意 :结果列表将包含Home和Away夹具,根据您的网格,您将需要执行此操作。

class Fixture { public string Home { get; set; } public string Away { get; set; } } void CallCode() { string players = new string[] { "A", "B", "C", "D" }; List fixtures = CalculateFixtures(players); } List CalculateFixtures(string[] players) { //create a list of all possible fixtures (order not important) List fixtures = new List(); for (int i = 0; i < players.Length; i++) { for (int j = 0; j < players.Length; j++) { if (players[i] != players[j]) { fixtures.Add(new Fixture() { Home = players[i], Away = players[j] }); } } } fixtures.Reverse();//reverse the fixture list as we are going to remove element from this and will therefore have to start at the end //calculate the number of game weeks and the number of games per week int gameweeks = (players.Length - 1) * 2; int gamesPerWeek = gameweeks / 2; List sortedFixtures = new List(); //foreach game week get all available fixture for that week and add to sorted list for (int i = 0; i < gameweeks; i++) { sortedFixtures.AddRange(TakeUnique(fixtures, gamesPerWeek)); } return sortedFixtures; } List TakeUnique(List fixtures, int gamesPerWeek) { List result = new List(); //pull enough fixture to cater for the number of game to play for (int i = 0; i < gamesPerWeek; i++) { //loop all fixture to find an unused set of teams for (int j = fixtures.Count - 1; j >= 0; j--) { //check to see if any teams in current fixtue have already been used this game week and ignore if they have if (!result.Any(r => r.Home == fixtures[j].Home || r.Away == fixtures[j].Home || r.Home == fixtures[j].Away || r.Away == fixtures[j].Away)) { //teams not yet used result.Add(fixtures[j]); fixtures.RemoveAt(j); } } } return result; } 
 var games = players.SelectMany((player1, index) => players.Skip(index + 1). Select(player2 => new {Player1 = player1, Player2 = player2})); 

应该这样做……

我真正想要的实现:

 public static List>> ListMatches(List listTeam) { var result = new List>>(); int numDays = (listTeam.Count - 1); int halfSize = listTeam.Count / 2; var teams = new List(); teams.AddRange(listTeam.Skip(halfSize).Take(halfSize)); teams.AddRange(listTeam.Skip(1).Take(halfSize - 1).ToArray().Reverse()); int teamsSize = teams.Count; for (int day = 0; day < numDays; day++) { var round = new List>(); int teamIdx = day % teamsSize; round.Add(new Tuple(teams[teamIdx], listTeam[0])); for (int idx = 1; idx < halfSize; idx++) { int firstTeam = (day + idx) % teamsSize; int secondTeam = (day + teamsSize - idx) % teamsSize; round.Add(new Tuple(teams[firstTeam], teams[secondTeam])); } result.Add(round); } return result; }