搜索哈希表并移动重复项

时间:2015-02-03 15:48:46

标签: arrays powershell hashtable

我有一个用于计算垒球比赛的脚本(实际上是任何运动)。该脚本使用循环风格计算来创建比赛,以便每个团队至少一次与其他团队比赛。此特定脚本允许您输入团队数量和游戏数量。根据游戏数量,您可以让团队互相玩2到3次。所以我也有脚本反转比赛来模拟Home vs Away,所以如果不止一次比赛,没有球队在主场上有优势。

显示最终输出时出现问题。我没有意识到每个游戏" (所有球队的一系列对决)一些球队在同一场比赛/周内被列出两次。我们不希望任何球队在同一周/比赛中进行两次比赛。 在脚本中,我采用了一系列匹配并将它们转换为哈希表,在那里它将比赛分组到球队数量/ 2。

如何重新排列有重复值的哈希表值并将其与另一个值交换#34; Game"没有球队打两次球的比赛(见下文)?



# Show input box popup and return the value entered by the user. 
function Read-InputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText) 
{
     Add-Type -AssemblyName Microsoft.VisualBasic
     return [Microsoft.VisualBasic.Interaction]::InputBox($Message, $WindowTitle, $DefaultText) 
}

#define numbers of teams and games maybe use fields later

$teams = Read-InputBoxDialog -Message "Number of teams:" -WindowTitle "Teams" -DefaultText "3"
if ($teams -eq "0") { Write-Host "You clicked Cancel" } 
elseif ([int]$teams -gt "2" -and [int]$teams -lt 13) { Write-Host -foreground yellow "$teams Teams" } 
else { Write-Host "You entered $teams which is higher than the 12 teams this was designed for" }


$fields = Read-InputBoxDialog -Message "Number of fields:" -WindowTitle "Teams" -DefaultText "2"
if ($fields -eq $null) { Write-Host "You clicked Cancel" } 
elseif ([int]$fields -gt "0" -and [int]$fields -lt "4") { Write-Host -foreground green "$fields Fields" }  
else { Write-Host "You entered $fields which is higher than the 3 fields this was designed for" }

$gamess= "0"
$allplay= [int]$teams-1
$gamess = Read-InputBoxDialog -Message "Number of Games:" -WindowTitle "Games" -DefaultText "12"
if ($gamess -eq 0) { Write-Host "No value specified" } 
elseif ([int]$gamess -lt $allplay) {Write-host -foreground red "You must have more than 2 minus the number of teams or there won't be enough matches" }
elseif ([int]$gamess -lt "34") { Write-Host -foreground cyan "$gamess Games" } 
else { Write-Host "You entered $gamess which is more than 3 times the number of teams" }

#build array of teams
$a= 1..$teams

#if teams is odd number add a bye team to symbolize a bye for the opponent, thus making the number of teams even again
if ($teams % 2 -eq 1){$a += "bye"}
$parts = $a.length/2

#functions for game and rotating arrays borrowed most of the code for this from: http://www.hanselman.com/blog/2008WindowScriptingGamesAdvancedPowerShellEvent7.aspx 
[array]$global:games = $nul
function rotateArray($a)
{
 $first, $rest = $a
 $a = $rest + $first
 return $a
}
#function for creating away matchups 1 at a time
function makeGamesA($a)
{
 $i = 0;
 while($i -lt $a.Length/2)
 {
  $global:games = $global:games + ($a[$i].ToString() + " v " + $a[$a.Length-1-$i].ToString())
  $i++
 }  
}
#function for creating home matchups one at a time
function makeGamesH($a)
{
 $i = 0;
 while($i -lt $a.Length/2)
 {
  $global:games = $global:games + ($a[$a.Length-1-$i].ToString() + " v " + $a[$i].ToString())
  $i++
 }  
}
#here we create X as the variable that decides whether this is an away or home game and run the matching function based on even or odd value.
$x = 1
$z = 0
while($z -lt $gamess)
{
 if ($z -eq [int]$x*($a.length-1)) {$x++}
 if ($x % 2 -eq 1) {makeGamesA($a)}
 else {makeGamesH($a)}
 # hold on to the first one
 
 $first, $rest = $a
 #rotate the rest
 $rest = rotateArray($rest)
 $a = [array]$first + $rest
 $z++
}
#Collect into long array of match ups
$a = [collections.arraylist]$global:games
#convert values into hash table for each game played 
$b = @{}
$count = 1
$a |% {$b[$count % $gamess] += @($_);$count++}
$b= $b.getEnumerator() | sort-object Name

# Setting formatting specifications for each column in a hash table:
$column1 = @{expression="Name"; width=10; `
label="Game"; alignment="left"}
$column2 = @{expression="Value"; width=40; `
label="Team Matchups: Home vs. Away"; alignment="right"}
$f= $b | Format-table $column1, $column2
#print it out on the screen.
$f
read-host -foreground cyan "press any key to when finished"




2 个答案:

答案 0 :(得分:0)

所以,如果我理解正确,你的意思是重复的比赛将是第1队与第2队,第2队与第1队,是吗?如果是这样,想象下面的“比赛网格”。考虑第一行,第一队不与自己匹配,但其余的则完成。在第2行,第2组不再与团队1匹配(重复)或本身,但它会完成剩下的工作,依此类推等等。

 |1|2|3|4|5|6
-+-+-+-+-+-+-
1|n|y|y|y|y|y
-+-+-+-+-+-+-
2|n|n|y|y|y|y
-+-+-+-+-+-+-
3|n|n|n|y|y|y
-+-+-+-+-+-+-
4|n|n|n|n|y|y
-+-+-+-+-+-+-
5|n|n|n|n|n|y
-+-+-+-+-+-+-
6|n|n|n|n|n|n

此代码将生成网格,假设有6个团队。它现在只是通过数字,但你可以轻松地遍历团队列表而不是数字。既然你已经采取措施确保拥有一支偶数的团队,那么你们已经完成了所有工作!

for($i=0; $i -lt 6; $i++){
    [string]$str = ""
    for($j=0; $j -lt 6; $j++){
        if($i -ge $j){ $str = "$str n" }
        else{ $str = "$str y" }
    }
    Write-Output "$str `n"
}

要进一步细化为团队与团队的列表,这是一个例子。

$teams = @("Packers","Raiders","Patriots","Seahawks","Browns","Cowboys")

for($i=0; $i -lt $teams.Count; $i++){
    for($j=0; $j -lt $teams.Count; $j++){
        if($i -lt $j){
            Write-Output "$($teams[$i]) vs. $($teams[$j])"
        }
    }
}

Packers vs. Raiders
Packers vs. Patriots
Packers vs. Seahawks
Packers vs. Browns
Packers vs. Cowboys
Raiders vs. Patriots
Raiders vs. Seahawks
Raiders vs. Browns
Raiders vs. Cowboys
Patriots vs. Seahawks
Patriots vs. Browns
Patriots vs. Cowboys
Seahawks vs. Browns
Seahawks vs. Cowboys
Browns vs. Cowboys

答案 1 :(得分:0)

我做了一些思考并在纸上绘制了比赛,并且无法弄清楚为什么我不会在一个游戏系列中出现两次出现的球队的单个实例。然后我意识到我从原始阵列到哈希表的转换导致匹配以不同方式排序,从而导致重复(为了澄清,请参阅我对坎贝尔回答的评论)。我决定改变它并让它将数组转换成另一个数组,用#of team除以2来对比赛进行分组。



function Split-Collection {
        [CmdletBinding()]
        param(
            [Parameter(ValueFromPipeline=$true)] $Collection,
            [Parameter(Mandatory=$true)][ValidateRange(1, 247483647)][int] $Count
        )
        begin {
            $Ctr = 0
            $Arrays = @()
            $TempArray = @()
        }
        process {
            if (++$Ctr -eq $Count) {
                $Ctr = 0
                $Arrays += , @($TempArray + $_)
                $TempArray = @()
                return
            }        
            $TempArray += $_ 
        }
        end {
        if ($TempArray) { $Arrays += , $TempArray }
        $Arrays
      }
    }

    #split up the array output the values to the form variable.

    $b = $a | Split-collection -Count $parts | %{ $_ -join ' | '}




我的输出现在看起来像这样:这是所需的效果。每个游戏都代表了可以同时进行的所有比赛。

比赛20:1 v 4 | 5 v 3 | bye v 2

比赛21:1 v 5 | bye v 4 | 2 v 3

第22场比赛:bye v 1 | 5 v 2 | 4 v 3

比赛23:2 v 1 | bye v 3 | 5 v 4

比赛24:3 v 1 | 2 v 4 | bye v 5