如何将哈希表添加到多维数组中?无法通过成员访问枚举赋值 [英] How to add hashtable to multidimensional array? Cannot assign values via member-access enumeration

查看:0
本文介绍了如何将哈希表添加到多维数组中?无法通过成员访问枚举赋值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将哈希表添加到多维数组时遇到了问题。我编写了以下代码:

$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:SkripteibV2-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"上吗?

推荐答案

tl;dr

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

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

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

注意:这假设:

  • 数组$Data.BIBs.BIB1中只有一个元素有.Bücher属性(Key)
  • 如果属性/键确实存在,则它是非空,因此在布尔上下文中是真实的,例如传递给?(Where-Object)的表达式;与成员访问枚举一样,这个简化的Where-Object语法-? Bücher而不是? { $_.Bücher }-是称为比较语句的PSv3+功能。

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

PowerShell在获取值的集合值属性与设置值的属性之间故意存在点符号不对称。

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

  • 设置上,应用成员访问枚举;其原因是意外修改数据的风险太高-请参见GitHub issue #5271,特别是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放弃成员访问枚举,因此无法直接在[object[]]实例上查找.b3属性,当然,数组没有.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.
...

这篇关于如何将哈希表添加到多维数组中?无法通过成员访问枚举赋值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆