将PowerShell对象扁平化

编程语言 2026-07-12

如果我有一个嵌套列表,例如:

$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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章