PowerShell:如何根据嵌套字典属性对有序字典排序?
按嵌套键值对PowerShell有序字典排序
需要对PowerShell中的有序字典,根据字典项内嵌套键的值进行排序。例如:
$data = [Ordered]@{ '1' = @{'thing' = "3"} '2' = @{'thing' = "2"} '3' = @{'thing' = "1"} }
按thing的值排序后,期望得到如下有序字典:
$ordered = [Ordered]@{ '3' = @{'thing' = "1"} '2' = @{'thing' = "2"} '1' = @{'thing' = "3"} }
已知可以使用.GetEnumerator()按字典自身的键排序,但不清楚如何基于嵌套键的值排序,并将排序后的项添加到新的[Ordered]字典中。尝试了以下代码,但在foreach环节报错:
$data = [Ordered]@{ '1' = @{'thing' = "3"} '2' = @{'thing' = "2"} '3' = @{'thing' = "1"} } $ordered = [ordered]@{} foreach ($item in ($keyStatus.GetEnumerator() | Select-Object Value | Sort-Object -Property Value)) { $ordered[$item.Key] = $item.Value }
实际场景中的数据结构如下({GUID}为不同的实际GUID值),需按DisplayName进行排序:
$data = [Ordered]@{ '{GUID1}' = @{'DisplayName' = "Program A"; 'DisplayVersion' = '1.2'} '{GUID2}' = @{'DisplayName' = "Program Z"; 'DisplayVersion' = '0.5'} '{GUID3}' = @{'DisplayName' = "Program M"; 'DisplayVersion' = '3.4'} }
问题分析
尝试的代码存在三个问题:
- 变量名错误:使用了未定义的
$keyStatus,应该替换为目标字典变量$data Select-Object Value会丢弃键值对的Key属性,导致后续无法通过$item.Key获取外层键- 排序时未指定嵌套键路径,直接用
Value作为排序属性不符合需求
解决方案
通用步骤
- 调用字典的
.GetEnumerator()方法,获取所有键值对的枚举器 - 使用
Sort-Object指定嵌套键的完整路径(如Value.thing或Value.DisplayName)作为排序依据 - 遍历排序后的键值对,逐个添加到新的有序字典中
示例1:按thing值排序
$data = [Ordered]@{ '1' = @{'thing' = "3"} '2' = @{'thing' = "2"} '3' = @{'thing' = "1"} } $ordered = [ordered]@{} # 按Value.thing升序排序,保留键值对的Key和Value属性 foreach ($item in $data.GetEnumerator() | Sort-Object -Property Value.thing) { $ordered[$item.Key] = $item.Value } # 输出排序结果 $ordered
示例2:按DisplayName排序(实际场景)
$data = [Ordered]@{ '{GUID1}' = @{'DisplayName' = "Program A"; 'DisplayVersion' = '1.2'} '{GUID2}' = @{'DisplayName' = "Program Z"; 'DisplayVersion' = '0.5'} '{GUID3}' = @{'DisplayName' = "Program M"; 'DisplayVersion' = '3.4'} } $ordered = [ordered]@{} # 按DisplayName字典序升序排序 foreach ($item in $data.GetEnumerator() | Sort-Object -Property Value.DisplayName) { $ordered[$item.Key] = $item.Value } # 输出排序结果 $ordered
额外选项
- 若需降序排序,添加
-Descending参数:Sort-Object -Property Value.DisplayName -Descending - 若存在嵌套键缺失的项,可添加
-ErrorAction SilentlyContinue忽略排序错误,或提前过滤无效项:$validItems = $data.GetEnumerator() | Where-Object { $_.Value.ContainsKey('DisplayName') } foreach ($item in $validItems | Sort-Object -Property Value.DisplayName) { $ordered[$item.Key] = $item.Value }
内容的提问来源于stack exchange,提问作者Gordon
相关产品推荐
相关产品推荐

