【发布时间】:2021-06-13 00:24:57
【问题描述】:
我有两个对象数组。
$animals 包含每个动物一个对象,其属性为“id”、“sort”和“alive”(“yes”或“no”)。
$inventory 为 $animals 中的每个动物(在“id”上匹配)包含一个匹配对象,其信息(属性)为“id”、“type”和“validated”($true 或 $false)。
我想在 $animals 中循环遍历我的所有动物,其中 "alive=yes" 并且:
- 如果 $inventory 中的“type=reptile”,则不执行任何操作。
- 将动物送到 $inventory 中“validated=$false”的兽医处。
代码:
$animals = @(
[pscustomobject]@{id=1;sort='cat';alive='yes'}
[pscustomobject]@{id=2;sort='dog';alive='yes'}
[pscustomobject]@{id=3;sort='mouse';alive='no'}
[pscustomobject]@{id=4;sort='anaconda';alive='yes'}
[pscustomobject]@{id=5;sort='cobra';alive='yes'}
)
$inventory = @(
[pscustomobject]@{id=1;type='mammal';validated=$false}
[pscustomobject]@{id=2;type='mammal';validated=$true}
[pscustomobject]@{id=3;type='mammal';validated=$false}
[pscustomobject]@{id=4;type='reptile';validated=$false}
[pscustomobject]@{id=5;type='reptile';validated=$true}
)
foreach ($animal in $($animals.Where( {$_."alive" -eq "yes"} ))) {
if ($inventory.Where( { (($_."id" -eq $animal."id") -and ($_."type" -eq "reptile")) } )) {
"Skip"
} elseif ($inventory.Where( { (($_."id" -eq $animal."id") -and ($_."validated" -eq $false)) } )) {
"Email vet: $($animal) needs to be validated!"
}
}
虽然这工作得很好,但循环遍历所有“type=reptile”是非常低效的,即使我不打算对它们做任何事情。如果我能以某种方式直接在我的 foreach 中或在进入 foreach 之前以某种方式整理出“type=reptile”,那将更有效(也更优雅)。有谁知道以比示例更有效的方式直接在 foreach 中或之前整理“type=reptile”的任何方法?
【问题讨论】:
-
将两个导入的数组合并为一个数组,然后使用复合
Where-Object测试根据需要包含或排除。 -
正如@Lee_Dailey 建议的那样,我打算使用add a Join-Object cmdlet to the standard PowerShell equipment
#14994来促进一个简单的($animals |Join $inventory -on Id |Where alive -eq 'yes' ...) 语法。否则,您可能希望基于id创建一个哈希表来链接这些表。
标签: arrays powershell object conditional-statements