我在向多维数组中添加哈希表时遇到了问题。我编写了以下代码:
$Data = @{BIBs = @(
@{$BIB = @{BIBName=$BIBName},
@{Standort = $Standort},
@{Bücher = @(
@{BuchName = $BuchName;
Autor = $Autor
})
}}
)}
这段代码运行并创建了一个输出,我将其存储在JSON中:
{
"BIBs": [
{
"BIB1": [
{
"BIBName": "123"
},
{
"Standort": "123"
},
{
"Bücher": [
{
"Autor": "123",
"BuchName": "123"
}
]
}
]
},
{
"BIB2": [
{
"BIBname": "345"
},
{
"Standort": "345"
},
{
"Bücher": [
{
"Autor": "345",
"Buchname": "345"
}
]
}
]
}
]
}
我有额外的代码添加另一个哈希表数组“BIBs”,你可以看到。
$jsonfile = "C:\Skripte\bibV2-1000.json"
$Data = Get-Content $jsonfile | ConvertFrom-Json
$Data.BIBs += New-Object -TypeName PSObject -Property @{
$BIB = @{BIBname=$BIBName}, @{Standort=$Standort},
@{Bücher = @(@{Buchname=$BuchName;Autor=$Autor})}
}
当输出像上面一样时,我无法向“Bücher”添加另一个哈希表。我查了“Bücher”的类型
$data.BIBs.BIB1.Bücher.GetType()
它实际上是一个数组
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
我尽力了
$Data.BIBs.BIB1.Bücher += @{Person="Max";Alter="35"}
添加一个新的哈希表,就像我对“BIB2”所做的那样,但我得到了错误:
The property 'Bücher' cannot be found on this object. Verify that the property
exists and can be set.
At line:5 char:1
+ $data.BIBs.BIB1.Bücher += @{Motor="asdf";pers="345"}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
你知道我怎么把@{Person="Max";Alter="35"}
加到“Bücher”上吗
1条答案
按热度按时间6mw9ycah1#
tl;dr
不支持 * 通过 member-access enumeration 设置 * 键/属性值(见下文)。
而必须获取要显式修改
.Bücher
属性的具体对象:注:假设:
$Data.BIBs.BIB1
中只有 one 个元素具有.Bücher
属性(key)?
(Where-Object
)的表达式;与成员访问枚举类似,这种简化的Where-Object
语法(? Bücher
而不是? { $_.Bücher }
)是PSv 3+的特性,称为simplified syntax。Mathias R. Jessen在对这个问题的评论中提供了关键的指针:
PowerShell在 collection-valued 属性的点表示法方面故意不对称,用于 getting 值与 * 设置 * 值。
*在 getting 上,PSv 3+应用member-access enumeration,简而言之,它允许您访问 collection 上的属性,并隐式地从 each element IN that collection 获取该属性的值,结果收集在 array 中。
*设置 * 时,成员访问枚举 * 不 * 应用;理由是无意修改数据的风险太高-请参见GitHub issue #5271,特别是PS团队核心成员的评论。
不幸的是,当前的错误消息并没有告诉你。
它源于这样一个事实,即当试图在集合级别 * 设置 * 一个属性时,该属性只会 * 直接在集合 * 上(而不是在其元素上)查找,而它(通常)并不存在。
让我们看一个简化的例子:
在****上,一切工作正常**:
即使
$data.a
是一个[object[]]
数组,也会在其 * 元素 * 中找到具有.b3
属性的对象(哈希表),并输出该对象的.b3
值。这是成员访问枚举的作用(尽管更典型的用法是属性存在于数组的 all 元素上,以及单个值被收集到
[object[]]
数组中)。在 * 设置*时,PowerShell放弃了成员访问枚举,因此**只能 * 在
[object[]]
示例$data.a
上直接查找.b3
属性失败,当然,数组没有.b3
属性: