将PowerShell对象扁平化
如果我有一个嵌套列表,例如:
$nested=[pscustomobject]@{set="A"; lst=[pscustomobject]@{Id=1; Name="One"},[pscustomobject]@{Id=2; Name="Two"}} `
, [pscustomobject]@{set="B"; lst=[pscustomobject]@{Id=1; Name="One"},[pscustomobject]@{Id=3; Name="Three"}}
如何仅用一个表达式就能得到像下面这样的“扁平化”列表(所以不使用过程式循环结构)
Set Id Name
--- -- -----
A 1 One
A 2 Two
B 1 One
B 3 Three
作为一个额外的问题,我该如何只筛选出2/"Two"?我可以这样做:
$nested|Where-Object {$_.lst.Id -eq 2}
尽管那样会找到集合A,但Id 1也会被包含在内,而我只想要Id 2,因此不是
set lst
--- ---
A {@{Id=1; Name=One}, @{Id=2; Name=Two}}
我想要
Set Id Name
--- -- -----
A 2 Two
我已经搜索了很多,看到有一些脚本可以完全扁平化一个对象(例如 Flatten-Object),但没有一个简单的方法让你自己直接输入,而不让JSON来承担繁重的工作。
解决方案
Here's an option if you really want it as an inline expression (any performance considerations notwithstanding):
$flattened = $nested | foreach-object {
# capture "outer" automatic variable so we can reference it in the inner foreach-object
$outer = $_
$_.lst | foreach-object {
[pscustomobject] @{
Set = $outer.set
Id = $_.Id
Name = $_.Name
}
}
}
$flattened
# Set Id Name
# --- -- ----
# A 1 One
# A 2 Two
# B 1 One
# B 3 Three
And then to filter your items:
$my_value = $flattened | where-object { $_.Id -eq 2 }
$my_value
# Set Id Name
# --- -- ----
# A 2 Two
You can also tack the where-object onto the end of the original expression as an additional pipeline component if you don't care about capturing the flattened list for other purposes:
$my_value = $nested | foreach-object {
$outer = $_
$_.lst | foreach-object {
[pscustomobject] @{
Set = $outer.set
Id = $_.Id
Name = $_.Name
}
}
} | where-object { $_.Id -eq 2 }
$my_value
# Set Id Name
# --- -- ----
# A 2 Two
Or you can filter the values on the fly if you don't mind coupling the transformation and filtering logic:
$my_value = $nested | foreach-object {
$outer = $_
$_.lst `
| where-object { $_.Id -eq 2 } `
| foreach-object {
[pscustomobject] @{
Set = $outer.set
Id = $_.Id
Name = $_.Name
}
}
}
$my_value
# Set Id Name
# --- -- ----
# A 2 Two
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。