问题描述
我构建了一个递归解决方案,以读取JSON文档并输出平坦表。现在我想反转操作,但是很难找出孤子。我需要将其安装在PowerShell中,因为我只想将其添加到现有模块中。
我在此处发布了有关我的展平代码的信息:https://stackoverflow.com/a/63499156/13224569
我有一个部分解决方案,但是很短。这是代码:
$a = '.person.pets[0].color.black.toy.foo' -split '\.'
$b = '.john.harold.cravener' -split '\.'
$z = '.john.is.content' -split '\.'
$m = @{}
$c = @{}
$p = @{}
$pk = $null
$firstTime = $true
foreach($i in $a[1..($a.Count-1)]) {
$c = @{$i = $null}
if($firstTime){
$m = $c
$firstTime = $false
}
if($p -and $pk) {
$p[$pk] = $c
}
$p = $c
$pk = $i
}
$m
exit
这是它的输出:
PS D:\> .\tester.ps1 | ConvertTo-Json -Depth 20
{
"person": {
"pets[0]": {
"color": {
"black": {
"toy": {
"foo": null
}
}
}
}
}
}
我的第一个挑战是,我不知道如何继续下一行并将其存储到现有的$ m变量中。我不知道在PowerShell / .Net Core中引用此var的方式。
第二个挑战是如何处理数组,但我什至还没有开始。
任何人和所有帮助/建议将不胜感激!
解决方法
经过一些研究,以及大量的工作和调试,我找到了一个解决方案。从我到目前为止的测试来看,它运行良好。它基于simonw的python代码here。尽管我的解决方案需要安装在PowerShell中,但它不是直接端口,而是非常接近的端口。大多数修改都是基于PowerShell和Python处理某些事情的方式上的差异。主要功能是 ConvertFrom-JhcUtilJsonTable ,该功能又取决于三个帮助器功能。这都是他们。
function ConvertFrom-JhcUtilJsonTable {
param (
[Parameter(Mandatory = $true,ValueFromPipeline = $true)]
[System.Collections.Hashtable]
$jsonHashTable
)
begin {}
process {
foreach ($h in $jsonHashTable) {
$m = @{}
foreach ($k in $h.Keys) {
$current = $m
$val = $h[$k]
$k = ($k -replace '\]','') -replace '\[','.'
$bits = $k.split('.')
$path = $bits[1..($bits.Count - 1)]
$count = 0
foreach ($bit in $path) {
$count++
if ($v = $current.item($bit)) {
$current[$bit] = $v
}
else {
if ($count -eq $path.Count) {
$current[$bit] = $val
}
else {
$current[$bit] = @{}
}
}
$current = $current[$bit]
}
}
intKeyHashToLists -obj $m
#--python code had a buit about handling root units e.g. {'$empty': '{}'} - need to add that
}
}
end {}
}
#---helper function for ConvertFrom-JhcUtilJsonTable
#
function isType {
param (
[Parameter(Mandatory)]
[System.Object]
$obj,[Parameter(Mandatory)]
[ValidateSet('Hashtable','Object[]')]
[System.String]
$typeName
)
$t = $obj.GetType()
if ($t.Name -eq $typeName) {
return $true
}
return $false
}
#---helper function for ConvertFrom-JhcUtilJsonTable
#
function allKeysDigits {
param (
[Parameter(Mandatory)]
[System.Collections.Hashtable]
$h
)
foreach ($k in $h.Keys) {
if ($k -match '^0\d') {
return $false
}
if ($k -notmatch '^\d+$') {
return $false
}
}
return $true
}
#---helper function for ConvertFrom-JhcUtilJsonTable
#
function intKeyHashToLists {
param (
[Parameter(Mandatory)]
[System.Object]
$obj
)
if (isType -obj $obj -typeName 'Hashtable') {
if ($obj -and (allKeysDigits -h $obj)) {
$a = @()
foreach ($k in ($obj.Keys | Sort-Object) ) {
$a += intKeyHashToLists -obj $obj.item($k)
}
return,$a #--- adding the comma forces this to retun an array even when it's a single element
}
else {
$h = @{}
foreach ($k in $obj.Keys) {
$h[$k] = intKeyHashToLists -obj $obj.item($k)
}
return $h
}
}
elseif (isType -obj $obj -typeName 'Object[]') {
return ( $obj | ForEach-Object { intKeyHashToLists -obj $_ } )
}
else {
return $obj
}
}