递归排序嵌套哈希表键的PowerShell代码问题排查
问题排查:哈希表嵌套层级按键排序时结构错误修复
问题描述
需要对哈希表所有嵌套层级的属性按键排序,但重构对象结构时出错:$keyFull被当作键名而非路径,输出出现"main.nested": {}的错误结构,预期应为嵌套的"main": { "nested": {} }形式。
原代码
function sortAlphabeticallyRecursive( $hashtable ) { $sorted = [Ordered] @{ } function sortNested { param( [System.Object] $hashtable, [String] $keyFull ) $hashtable.keys | ForEach-Object { if( $hashtable.$($_).Keys ) { if( $keyFull ) { $keyFull = "$keyFull.$_" } else { $keyFull = "$_" } if( ! $sorted.$($keyFull) ) { $sorted.$($keyFull) = @{} } sortNested $hashtable.$($_) "$keyFull" } else { $hashtable.keys | ForEach-Object { ( $hashtable.GetEnumerator() | sort key ) | ForEach-Object { $sorted.($keyFull).($_.key) = $_.value } } } } } sortNested( $hashtable, $null ) return $sorted } $hashtable = @{ 'main' = @{ 'nested' = @{ 'aba' = '2'; 'aaa' = '1'; 'aca' = '3' } } } $sorted = sortAlphabeticallyRecursive( $hashtable ) $sorted | ConvertTo-Json -Depth 100
原输出
{ "main": {}, "main.nested": { "aca": "3", "aba": "2", "aaa": "1" } }
预期输出
{ "main": { "nested": { "aca": "3", "aba": "2", "aaa": "1" } } }
问题分析
- 核心错误:用拼接的字符串键(如
"main.nested")直接给顶级哈希表赋值,PowerShell会将其视为单个顶级键名,而非嵌套路径,导致结构错误。 - 递归逻辑混乱:递归调用时未维护当前层级的哈希表引用,而是错误传递拼接后的键路径;else块重复遍历键,且未正确关联到对应嵌套层级。
- 哈希表类型问题:创建嵌套哈希表时未使用有序哈希表
[Ordered]@{},可能导致排序失效。
修复后的代码
function sortAlphabeticallyRecursive( $hashtable ) { # 递归处理单个哈希表的核心逻辑 function processNested($inputHashtable) { $sortedTable = [Ordered]@{ } # 先对当前层级的键排序 $inputHashtable.GetEnumerator() | Sort-Object Key | ForEach-Object { $key = $_.Key $value = $_.Value if ($value -is [System.Collections.IDictionary]) { # 如果值是哈希表,递归处理后赋值 $sortedTable[$key] = processNested $value } else { # 非哈希表值直接赋值 $sortedTable[$key] = $value } } return $sortedTable } return processNested $hashtable } $hashtable = @{ 'main' = @{ 'nested' = @{ 'aba' = '2'; 'aaa' = '1'; 'aca' = '3' } } } $sorted = sortAlphabeticallyRecursive $hashtable $sorted | ConvertTo-Json -Depth 100
修复说明
- 递归逻辑简化:每个层级独立处理,直接返回当前层级的有序哈希表,递归处理子哈希表后直接赋值给当前层级的键,自然形成嵌套结构。
- 层级键排序:每个层级先通过
Sort-Object Key对键排序,再处理值,确保所有层级的键都按字母顺序排列。 - 正确维护嵌套结构:避免使用拼接键路径的方式,直接通过哈希表引用赋值,保证结构正确。
验证结果
运行修复后的代码,输出与预期完全一致:
{ "main": { "nested": { "aaa": "1", "aba": "2", "aca": "3" } } }
内容的提问来源于stack exchange,提问作者MegaBomber
相关产品推荐
相关产品推荐

