【发布时间】:2016-12-09 18:08:06
【问题描述】:
我正在从 json 文件制作 PSObject
bar.json
{
"derp": {
"buzz": 42
},
"woot": {
"toot": 9000
}
}
我可以使用 ConvertFrom-Json 从 json 中创建一个 PSCustomObject
$foo = Get-Content .\bar.json -Raw |ConvertFrom-Json
$foo.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
但是,如果我尝试分解多个 json 文件,我会得到一个数组
$foo = Get-Content .\*.json -Raw |ConvertFrom-Json
$foo.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False Object[] System.Array
为了遍历 $foo,我需要 2 个不同的代码路径,具体取决于对象类型。
我可以从多个 json 文件中获取单个对象吗?
如果没有,我将如何将一组对象压缩成一个对象?
我尝试创建一个新对象$bar,其中包含$foo 的所有数组项
$bar = new-object psobject
$bar | add-member -name $foo[0].psobject.properties.name -value $foo[0].'derp' -memberType NoteProperty
更新
根据沃尔特米蒂的要求。如果我加载单个文件并运行$foo[0]
$foo = Get-Content .\bar.json -Raw |ConvertFrom-Json
$foo[0].gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
$foo[0]
derp woot
------------ ------------
@{Provisioners=System.Object[]; OS=windows; Size=; V... @{Provisioners=System.Object[]; OS=windows; Size=; V...
解决方案
我最初实现了 AP 的答案,但后来将其重构为使用 mklement0 答案。
虽然 $allObjects 是一个数组,但它仍然允许我按名称引用值,这正是我所寻找的
$allObjects = @(
Get-ChildItem '.\foo' -Filter *.json -Recurse | Get-Content -Raw | ConvertFrom-Json
)
# iterating over nested objects inside an array is hard.
# make it easier by moving all array objects into 1 parent object where
# the 'key' is the name (opposed to AP's answer where filename = key)
$newObject = New-Object PSObject
foreach ($i in $allObjects) {
$i.psobject.members | ?{$_.Membertype -eq 'noteproperty'} |%{$newObject | add-member $_.Name $_.Value}
}
【问题讨论】:
-
如果两个 json 文件/对象具有相同的属性但值不同,您会发生什么?
-
好点,如果任何键不是唯一的,我预计会出错
-
我可能错了,但我认为对象数组就是一个对象。
-
尝试 "$foo[0].gettype" 或 "$foo[0] | gm" 以了解有关 $foo 中第一个条目的更多信息。