powershell 嵌套pscustomobject数组的区分大小写筛选

xsuvu9jc  于 2023-10-18  发布在  Shell
关注(0)|答案(2)|浏览(134)

我需要帮助来调试我创建的以下示例代码,以模拟一个真实的场景,在该场景中,根据嵌套的pscustomobject属性与$filterTags中存储的值的区分大小写匹配来过滤$objects pscustomobject数组。

  1. # Filtering on the following strings. ***Must match case***
  2. $filterTags = @("application","environment")
  3. $objects = @(
  4. [PSCustomObject]@{ Name = "Object1"; tags = [PSCustomObject]@{ "Application" = "App1"; Environment = "Env1" }},
  5. [PSCustomObject]@{ Name = "Object2"; tags = [PSCustomObject]@{ "Application" = "App2"; environment = "Env2" }},
  6. [PSCustomObject]@{ Name = "Object3"; tags = [PSCustomObject]@{ "application" = "App3"; Environment = "Env3" }},
  7. [PSCustomObject]@{ Name = "Object4"; tags = [PSCustomObject]@{ "Migrate Project" = "Migration1"}}
  8. )
  9. $objects | Where-Object {
  10. $tagsNames = $_.tags.PSObject.Properties.Name
  11. $filterTags | ForEach-Object { $tagsNames -ceq $_ }
  12. }
  13. Name tags
  14. ---- ----
  15. Object2 @{Application=App2; environment=Env2}
  16. Object3 @{application=App3; Environment=Env3}
  17. Object4 @{Migrate Project=Migration1}

我只期望对象2和3由最后一个语句返回。对象1和对象4不匹配,所以对象1被过滤掉是很好的,但为什么对象4会出现呢?
当我运行下面的代码时,我得到了预期的False值,因为它是唯一一个不匹配的标记,所以我不明白为什么它会出现在上面的代码中。

  1. # variable set from previous code final loop
  2. $tagsNames
  3. Migrate Project
  4. $myTags | ForEach-Object { $tagsNames -ceq $_ }
  5. False
  6. False

我尝试了以下方法,使用了ccontains,它忽略了对象4,但返回对象1、2和3。

  1. $objects | Where-Object {
  2. $_.tags.PSObject.Properties.Name | % {$myTags -ccontains $_ }
  3. }

Tia

k5ifujac

k5ifujac1#

答案是因为一个包含多个元素的集合强制为$true,不管它们的元素是什么。参见从集合类型转换

  • 单元素集合的计算结果是其唯一元素的布尔值。
  • 多于1个元素的集合总是$true

您的筛选条件应该使用Where-Object.Where,而不是ForEach-Object。在这种情况下,.Where更好,因为它具有First模式,它更有效,因为它的行为类似于Enumerable.Any

  1. $objects | Where-Object {
  2. $tagsNames = $_.tags.PSObject.Properties.Name
  3. $filterTags.Where({ $tagsNames -ceq $_ }, 'First')
  4. }
h6my8fg2

h6my8fg22#

有趣的是,我找到了一个使用cmatch的解决方案。

  1. $objects | Where-Object {
  2. $_.tags.PSObject.Properties.Name | Where-Object {$myTags -cmatch $_ }
  3. }
  4. Name tags
  5. ---- ----
  6. Object2 @{Application=App2; environment=Env2}
  7. Object3 @{application=App3; Environment=Env3}

相关问题