json - Powershell 显示 JSON-object 和 ADDRESS-property 的错误输出
问题描述
我目前正在努力将 JSON 字符串转换为对象数组并通常处理每个对象的属性/属性。
这是一个简单的演示,显示例如属性“地址”似乎有点特殊:
cls
$json = '[{"id":"1","address":"1"},{"id":"2","address":"2"}]'
$list = $json | ConvertFrom-Json
$list.id # OK
$list.address # gives a weired result - is this a bug?
$list.GetEnumerator().address # that works
这是输出:
1
2
OverloadDefinitions
-------------------
System.Object&, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Address(int )
1
2
如您所见,我需要添加“.GetEnumerator()”以获得正确的“地址”值。
这是预期的吗?为了安全起见,我应该总是使用“.GetEnumerator()”吗?
解决方案
由于$list
是一个数组(集合),使用类似$list.id
执行成员枚举的东西;也就是说,在每个元素上.id
自动访问该属性,并将结果值作为数组 ( ) [1]返回。[object[]]
但是,如果数组/集合类型本身具有该名称的成员(属性或方法),它优先,这就是您的情况发生的情况:.NET 数组有一个.Address
方法(由运行时添加 - 请参阅此answer ),这就是抢占访问元素 .Address
属性的原因。
(您看到的是 PowerShell 对方法签名(重载)的表示,这是您仅按名称访问方法时得到的,而实际上没有通过附加 ( (...)
) 来调用它; try 'foo'.ToUpper
,fo 实例。)
解决该问题的最有效方法是使用PSv4+.ForEach()
数组方法,该方法始终以集合元素为目标:
$list = '[{"id":"1","address":"1"},{"id":"2","address":"2"}]' | ConvertFrom-Json
$list.ForEach('address')
警告:如果您正在运行Windows PowerShell,并且在某些$list
情况下可能只产生单个 pscustomobject
而不是数组,则必须将数组子表达式运算符括$list
在 中@(...)
,以确保该.ForEach()
方法可用。这是一个[pscustomobject]
特定的错误(假设即使是单个对象也应该始终有一个.ForEach()
方法),已在 PowerShell (Core) 6+ 中修复。
# @(...) is necessary in Windows PowerShell only.
@($list).ForEach('address')
笔记:
从技术上讲,这会返回一个
[System.Collections.ObjectModel.Collection[PSObject]]
集合,但在大多数情况下,您可以像使用常规[object[]]
PowerShell 数组一样使用它。与成员枚举不同,如果输入集合中只有一个元素,也会返回一个集合实例(而不是像成员枚举那样按原样返回一个元素的属性值)。
在PSv3-中,您可以使用ForEach-Object
cmdlet或Select-Object -ExpandProperty
:
$list | ForEach-Object address # PSv2: | ForEach-Object { $_.address }
# OR
$list | Select-Object -ExpandProperty address
[1] 如果集合中只有一个元素,则其属性值按原样返回,而不是包装在(单元素)数组中,这与在变量中收集管道输出时应用的逻辑相同。这个逻辑在成员枚举的上下文中可能是意料之外的,这是一个表达式上下文,正在这个 GitHub issue中讨论。
推荐阅读
- c++ - C++ 如何将两个 makefile 对象目标规则(位于另一个文件夹中)组合到一个目标/规则中?
- android - Lottie.Forms 中不存在类型或命名空间“Droid”
- python - 使用 tf.summary.image 显示 RNN 在 python tensorflow 中给出错误
- javascript - 如何在 JavaScript 中有条件地调用异步函数
- java - 如何定义整个spring项目的连接范围-web服务连接范围
- javascript - Shadow DOM 未在 DOM 中显示
- git - GithubDesktop 出错:“以下未跟踪的工作树文件将被结帐覆盖”
- node.js - 在没有单引号的情况下将 argv 从路由传递到 Node 中的脚本
- c# - Xamarin Forms 工具栏未在 Android 上显示
- c - C中的十六进制值除法