2013-08-01 3 views
9

Ich habe ein Problem beim Sortieren einer Hashtabelle. Ich habe meinen Code auf das Nötigste heruntergebrochen, um niemanden mit meinem ursprünglichen Skript zu überlisten.Sortieren Sie eine PowerShell-Hashtabelle für eine Eigenschaft mit dem Wert

Write-Host "PowerShell Version = " ([string]$psversiontable.psversion) 
$h = @{} 
$Value = @{SortOrder=1;v1=1;} 
$h.Add(1, $Value) 
$Value = @{SortOrder=2;v1=1;} 
$h.Add(2, $Value) 
$Value = @{SortOrder=3;v1=1;} 
$h.Add(3, $Value) 
$Value = @{SortOrder=4;v1=1;} 
$h.Add(4, $Value) 

Write-Host "Ascending" 
foreach($f in $h.GetEnumerator() | Sort-Object Value.SortOrder) 
{ 
    Write-Host $f.Value.SortOrder 
} 

Write-Host "Descending" 
foreach($f in $h.GetEnumerator() | Sort-Object Value.SortOrder -descending) 
{ 
    Write-Host $f.Value.SortOrder 
} 

Der Ausgang ist

PowerShell Version = 3.0 
Ascending 
2 
1 
4 
3 
Descending 
2 
1 
4 
3 

Ich bin sicher, dies ist nur ein einfacher Fall nicht die richtige Verwendung von Sort-Object zu kennen. Die Sortierung funktioniert korrekt auf Sort-Object Name, also hat es vielleicht etwas damit zu tun, dass man nicht mit der Value.SortOrder umgehen kann?

Antwort

19

Sort-Object akzeptiert einen Eigenschaftsnamen oder einen Skriptblock, der zum Sortieren verwendet wird. Da Sie auf eine Eigenschaft einer Eigenschaft zu sortieren sind versuchen, müssen Sie einen Skriptblock verwenden:

Write-Host "Ascending" 
$h.GetEnumerator() | 
    Sort-Object { $_.Value.SortOrder } | 
    ForEach-Object { Write-Host $_.Value.SortOrder } 

Write-Host "Descending" 
$h.GetEnumerator() | 
    Sort-Object { $_.Value.SortOrder } -Descending | 
    ForEach-Object { Write-Host $_.Value.SortOrder } 

können Sie filtern das Where-Object Cmdlets:

Write-Host "Ascending" 
$h.GetEnumerator() | 
    Where-Object { $_.Name -ge 2 } | 
    Sort-Object { $_.Value.SortOrder } | 
    ForEach-Object { Write-Host $_.Value.SortOrder } 

Sie wollen in der Regel zu put Where-Objectvor alle Sort-Object Cmdlets, da es das Sortieren schneller macht.

+0

Ich habe meine Frage aktualisiert, um den Code zu verwenden, den Sie erwähnten, aber ich bekomme immer noch die gleiche Ausgabe. –

+0

greymind sieht aus wie ich den Zeitraum verpasst habe. Ich bearbeite die Frage wieder auf das Original. –

+0

BTW das kann separate Frage sein, aber es gibt einen einfachen Weg zu> = 2 oder einem anderen Filter. –

2

Ich benutzte eine Hash-Tabelle als eine Häufigkeitstabelle, um das Auftreten von Wörtern in Dateinamen zu zählen.

$words = @{} 
get-childitem *.pdf | foreach-object -process { 
    $name = $_.name.substring($_.name.indexof("-") + 1, $_.name.indexof(".") - $_.name.indexof("-") - 1) 
    $name = $name.replace("_", " ") 
    $word = $name.split(" ")[0] 
    if ($words.contains($word)){ 
     $words[$word] = $words[$word] + 1 
    }else{ 
     $words.add($word, 1) 
    } 
} 
$words.getenumerator() | sort-object -property value 

Es ist die letzte Zeile, die die Magie der Fall ist, auf dem Wert, der die Hash-Tabelle Sortierung (Frequenz).

+0

Das ist eine brillante Antwort. Ich habe ein paar Stunden herum gestochert und so viele komplizierte Antworten gesehen, aber das funktioniert perfekt. Gut gemacht! Ich brauchte die Sortierung in einer Hashtabelle, aber es war eine einfache Sache $ hashtable = {was du geschrieben hast} zu setzen und es funktionierte großartig. Vielen Dank. – Alan

Verwandte Themen