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

时间:2018-03-15 10:27:46

标签: arrays powershell syntax hashtable member-enumeration

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

$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 个答案:

答案 0 :(得分:0)

<强> TL;博士

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

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

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

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

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

对于获取值与设置值的集合值属性,PowerShell有关于点表示法的故意不对称。

  • 获取时,PSv3 +会应用member enumeration ,简而言之,它允许您访问集合中的属性< / em>并隐式从该集合中的每个元素获取该属性的值,并将结果收集到数组中。

  • 设置上,成员枚举已应用;理由是无意中修改数据的风险太高 - 请参阅PS小组的核心成员this GitHub issue,特别是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的对象(哈希表),并且该对象&#39;输出s .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.
...