sorting - Orden de llaves de PowerShell Hashtables
order powershell-v2.0 (6)
La forma de PS1 de agregar un miembro de tabla hash conserva el orden de agregar. No es necesario utilizar System.Collections.Specialized.OrderedDictionary.
$Hash = New-Object PSObject
$Hash | Add-Member -MemberType NoteProperty -Name key1 -Value val1
$Hash | Add-Member -MemberType NoteProperty -Name key2 -Value val2
$Hash | Add-Member -MemberType NoteProperty -Name key3 -Value val3
Uso de Powershell 2.0 ¿Hay alguna forma de mantener el orden de las claves en una tabla hash a medida que se agregaron? Como un mecanismo push / pop.
Ejemplo:
$hashtable = @{}
$hashtable.Add("switzerland","berne")
$hashtable.Add("germany","berlin")
$hashtable.Add("spain","madrid")
$hashtable.Add("italy","rome")
$hashtable
Quiero conservar el orden en el que he agregado los elementos a la tabla hash.
Para compatibilidad con versiones anteriores de PowerShell, podría considerar este cmdlet:
Function Order-Keys {
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)][HashTable]$HashTable,
[Parameter(Mandatory = $false, Position = 1)][ScriptBlock]$Function,
[Switch]$Descending
)
$Keys = $HashTable.Keys | ForEach {$_} #Copy HashTable+KeyCollection
For ($i = 0; $i -lt $Keys.Count - 1; $i++) {
For ($j = $i + 1; $j -lt $Keys.Count; $j++) {
$a = $Keys[$i]
$b = $Keys[$j]
If ($Function -is "ScriptBlock") {
$a = $HashTable[$a] | ForEach $Function
$b = $HashTable[$b] | ForEach $Function
}
If ($Descending) {$Swap = $a -lt $b} Else {$Swap = $a -gt $b}
If ($Swap) {$Keys[$i], $Keys[$j] = $Keys[$j], $Keys[$i]}
}
}
Return $Keys
}
Este cmdlet devuelve una lista de claves ordenadas por la definición de función:
Ordenar por nombre:
$HashTable | Order-Keys | ForEach {Write-Host $_ $HashTable[$_]}
germany berlin
italy rome
spain madrid
switzerland berne
Ordenar por valor:
$HashTable | Order-Keys {$_} | ForEach {Write-Host $_ $HashTable[$_]}
germany berlin
switzerland berne
spain madrid
italy rome
También podrías considerar anidar tablas hash:
$HashTable = @{
switzerland = @{Order = 1; Capital = "berne"}
germany = @{Order = 2; Capital = "berlin"}
spain = @{Order = 3; Capital = "madrid"}
italy = @{Order = 4; Capital = "rome"}
}
Por ejemplo, ordenar por (hash) ordenar la propiedad y devolver la clave (país):
$HashTable | Order-Keys {$_.Order} | ForEach {$_}
O ordenar (descendiendo) por Capital predefinido
$HashTable | Order-Keys {$_.Capital} -Descending | ForEach {$_}
Puede dar una clave secuencial a medida que agrega elementos:
$hashtable = @{}
$hashtable[$hashtable.count]=@("switzerland","berne")
$hashtable[$hashtable.count]=@("germany","berlin")
$hashtable[$hashtable.count]=@("spain","madrid")
$hashtable[$hashtable.count]=@("italy","rome")
$hashtable
A continuación, puede obtener elementos ordenados por la clave:
echo "`nHashtable keeping the order as they were added"
foreach($item in $hashtable.getEnumerator() | Sort Key)
{
$item
}
Puedes usar un diccionario ordenado en su lugar: así:
$list = New-Object System.Collections.Specialized.OrderedDictionary
$list.Add("switzerland","berne")
$list.Add("germany","berlin")
$list.Add("spain","madrid")
$list.Add("italy","rome")
$list
no hay una solución integrada en powershell V1 / V2, querrá usar el sistema System.Collections.Specialized.OrderedDictionary
$order = New-Object System.Collections.Specialized.OrderedDictionary
$order.Add("switzerland","berne")
$order.Add("germany","berlin")
PS>$order
Name Value
---- -----
switzerland berne
germany berlin
En PS V3 puedes lanzar a [orden]:
PS>[ordered]@{"switzerland"="berne";"germany"="berlin"}
Name Value
---- -----
switzerland berne
germany berlin
function global:sortDictionaryByKey([hashtable]$dictionary)
{
return $dictionary.GetEnumerator() | sort -Property name;
}