在 powershell 中对哈希表中的多个值进行排序
Sort multiple values in hashtable in powershell
我在 PowerShell 中有一个哈希表,如下所示:
Profil = @{
"Jason" = "P2, P4, P1";
"Mick" = "P1";
"Rocky" = "P4, P5";
"Natasha" = "P9, P4, P1"
}
我需要删除空格并按如下方式排序:
Profil = @{
"Jason" = "P1,P2,P4";
"Mick" = "P1";
"Rocky" = "P4,P5";
"Natasha" = "P1,P4,P9"
}
我试了foreach($value in $Profil.GetEnumerator() | Sort Value) {$value.Value}
但是没用
以下 使用 foreach
语句 就地 更新散列 table (我已将 $Profil
替换为 $hash
,以避免与自动 $PROFILE
变量混淆。)
foreach ($key in @($hash.Keys)) {
$hash[$key] = ($hash[$key] -split ', *' | Sort-Object) -join ','
}
$hash # output the updated hash table
$hash.Keys
枚举散列table 的键以在循环中使用。
- 注意它周围的
@(...)
,这是有效克隆 .Keys
集合所必需的,以便允许更新循环内的散列table。
$hash[$key]
在循环内访问手头密钥的单个条目。
- 请注意,PowerShell 或者允许点符号 (
.
) 访问哈希-table 条目,就好像它们是属性一样,并且通常允许变量引用和表达式指定 属性名称,所以 $hash.key
也可以。
-split ', *'
通过逗号后跟零个或多个 (*
) 个空格将现有条目值拆分为标记。
| Sort-Object
对生成的标记进行排序。
-join ','
以逗号作为分隔符连接排序的标记。
使用管道也是一种选择,但通常较慢(虽然在许多用例中可能并不重要):
@($hash.Keys) | ForEach-Object {$hash[$_]= ($hash[$_] -split ', *' | Sort-Object) -join ','}
$Profil = @{
"Jason" = "P2, P4, P1"
"Mick" = "P1"
"Rocky" = "P4, P5"
"Natasha" = "P9, P4, P1"
}
# Create an empty Hashtable with a capacity equal or greater than the number of
# elements in $Profil
$ProfilSorted = [Hashtable]::New($Profil.Count)
foreach ($KeyAndValue in $Profil.GetEnumerator())
{
# RegEx split on a comma followed by whitespace.
[String[]]$Value = $KeyAndValue.Value -split ',\s*' |
Sort-Object
# Convert $Value from array of Strings to single String joined by commas.
[String]$Value = $Value -join ','
$ProfilSorted.Add($KeyAndValue.Key, $Value)
}
$Profil = $ProfilSorted
$Profil
您可能需要考虑将值存储为字符串数组 [String[]]
,而不是依赖文本拼接。
这应该有效:
$newProfil = @{}
$Profil.GetEnumerator() | foreach {
$newValue = (($_.Value -replace "\s","") -split ',' | Sort-Object) -join ','
$newProfil.add($_.Key, $newValue)
}
$newProfil
我在 PowerShell 中有一个哈希表,如下所示:
Profil = @{
"Jason" = "P2, P4, P1";
"Mick" = "P1";
"Rocky" = "P4, P5";
"Natasha" = "P9, P4, P1"
}
我需要删除空格并按如下方式排序:
Profil = @{
"Jason" = "P1,P2,P4";
"Mick" = "P1";
"Rocky" = "P4,P5";
"Natasha" = "P1,P4,P9"
}
我试了foreach($value in $Profil.GetEnumerator() | Sort Value) {$value.Value}
但是没用
以下 使用 foreach
语句 就地 更新散列 table (我已将 $Profil
替换为 $hash
,以避免与自动 $PROFILE
变量混淆。)
foreach ($key in @($hash.Keys)) {
$hash[$key] = ($hash[$key] -split ', *' | Sort-Object) -join ','
}
$hash # output the updated hash table
$hash.Keys
枚举散列table 的键以在循环中使用。- 注意它周围的
@(...)
,这是有效克隆.Keys
集合所必需的,以便允许更新循环内的散列table。
- 注意它周围的
$hash[$key]
在循环内访问手头密钥的单个条目。- 请注意,PowerShell 或者允许点符号 (
.
) 访问哈希-table 条目,就好像它们是属性一样,并且通常允许变量引用和表达式指定 属性名称,所以$hash.key
也可以。
- 请注意,PowerShell 或者允许点符号 (
-split ', *'
通过逗号后跟零个或多个 (*
) 个空格将现有条目值拆分为标记。| Sort-Object
对生成的标记进行排序。-join ','
以逗号作为分隔符连接排序的标记。
使用管道也是一种选择,但通常较慢(虽然在许多用例中可能并不重要):
@($hash.Keys) | ForEach-Object {$hash[$_]= ($hash[$_] -split ', *' | Sort-Object) -join ','}
$Profil = @{
"Jason" = "P2, P4, P1"
"Mick" = "P1"
"Rocky" = "P4, P5"
"Natasha" = "P9, P4, P1"
}
# Create an empty Hashtable with a capacity equal or greater than the number of
# elements in $Profil
$ProfilSorted = [Hashtable]::New($Profil.Count)
foreach ($KeyAndValue in $Profil.GetEnumerator())
{
# RegEx split on a comma followed by whitespace.
[String[]]$Value = $KeyAndValue.Value -split ',\s*' |
Sort-Object
# Convert $Value from array of Strings to single String joined by commas.
[String]$Value = $Value -join ','
$ProfilSorted.Add($KeyAndValue.Key, $Value)
}
$Profil = $ProfilSorted
$Profil
您可能需要考虑将值存储为字符串数组 [String[]]
,而不是依赖文本拼接。
这应该有效:
$newProfil = @{}
$Profil.GetEnumerator() | foreach {
$newValue = (($_.Value -replace "\s","") -split ',' | Sort-Object) -join ','
$newProfil.add($_.Key, $newValue)
}
$newProfil