如何将哈希表添加到多维数组?无法通过成员枚举分配值

问题描述 投票:2回答:1

我在将哈希表添加到多维数组时遇到了麻烦。我编码如下:

$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”吗?

arrays powershell syntax hashtable member-enumeration
1个回答
0
投票

tl;博士

不支持通过成员枚举设置键/属性值(参见下文)。

相反,您必须获取要明确修改其.Bücher属性的特定对象:

($Data.BIBs.BIB1 | ? Bücher).Bücher += @{ BuchName='neues Buch'; Autor='Johann Doe' }

注意:这假定: *只有$Data.BIBs.BIB1数组中的一个元素具有.Bücher属性(键) *如果属性/键确实存在,则它是非空的,因此在布尔上下文中是“truthy”,例如传递给?的表达式(Where-Object);像成员枚举一样,这个简化的Where-Object语法 - ? Bücher而不是? { $_.Bücher } - 是一个称为比较语句的PSv3 +特性。


Mathias R. Jessen在这个问题的评论中提供了关键指针:

对于获取值与设置值的集合值属性,PowerShell在点符号方面存在故意的不对称性。

  • 在获取时,PSv3 +应用member enumeration,简而言之,它允许您访问集合上的属性并隐式地从该集合中的每个元素获取该属性的值,并将结果收集到数组中。
  • 在设置时,不应用成员枚举;理由是,无意中修改数据的风险太高 - 请参阅this GitHub issue,尤其是PS团队的核心成员this comment

不幸的是,当前的错误消息并没有告诉你。 它源于这样的事实:当尝试在集合级别设置属性时,该属性仅直接在集合(而不是其元素)上查找,它通常不存在。

我们来看一个简化的例子:

$data = @{ # a hashtable
  a = ( # array of hashtables
    @{ b1 = 'b1' },
    @{ b2 = 'b2' },
    @{ b3 = 
      @{ b31 = 'b31' }, @{ b32 = 'b32' } # array of hashtables
    }
  )
}

在获取,一切正常:

PS> $data.a.b3

Name                           Value                                                                                                                                                                                                                            
----                           -----                                                                                                                                                                                                                            
b31                            b31                                                                                                                                                                                                                              
b32                            b32                                                                                                                                                                                                                              

尽管$data.a是一个[object[]]数组,但在其元素中找到了一个具有属性.b3的对象(哈希表),并输出该对象的.b3值。 这是运行中的成员枚举(尽管更典型的用法是属性存在于数组的所有元素上以及在[object[]]数组中收集各个值的情况)。

在设置时,PowerShell放弃了成员枚举,因此仅在.b3 [object[]]实例上直接查找$data.a属性失败,当然,数组没有.b3属性:

PS> $data.a.b3 += @{ b33 = 'b33' }  # Try to add an element; !! FAILS

The property 'b3' cannot be found on this object. 
Verify that the property exists and can be set.
...
© www.soinside.com 2019 - 2024. All rights reserved.