powershell - 如何使用 Powershell 中的多维数组的 where 子句执行 foreach 循环?

例如

$people = @(
 @('adam', '24', 'M')
 @('andy', '20', 'M')
 @('alex', '30', 'M')
 @('ava', '25', 'F')
)

foreach($person in $people | where ($person[1] -lt '25') -and ($person[2] -eq 'M'))

这应该选择 adamandy...

回答1

您应该为 Where-Object 语句使用的语法是:

$people = @(
    @('adam', '24', 'M'),
    @('andy', '20', 'M'),
    @('alex', '30', 'M'),
    @('ava', '25', 'F')
)

$people | Where-Object { $_[1] -lt '25' -and $_[2] -eq 'M' } | ForEach-Object { $_[0] }

# Results in:
#
# adam
# andy

或者使用带有 if 语句的传统 foreach 循环:

foreach($array in $people) {
    if($array[1] -lt 25 -and $array[2] -eq 'M') {
        $array[0]
    }
}

但是,正如先前答案中所建议的那样, https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_hash_tables?view=powershell-7.2 可能更适合于此(即使语法有点复杂):

$people = @{
    M = @{
        24 = 'adam'
        20 = 'andy'
        30 = 'alex'
    }
    F = @{
        25 = 'ava'
    }
}

$people['M'][$people['M'].Keys -lt 25]

回答2

您当然可以使用涉及 ForEach-Object 的答案。唯一可能的问题(取决于您尝试使用该数据做什么)是 ForEach-Object 将单独执行每条数据记录。

另一种方法是创建您想要的对象,然后使用标准的 foreach()。

$people = @(
 @('adam', '24', 'M')
 @('andy', '20', 'M')
 @('alex', '30', 'M')
 @('ava', '25', 'F')
)

$filteredPeople = $people | Where-Object { $_[1] -lt '25' -and $_[2] -eq 'M'}

foreach($person in $$filteredPeople) {

#stuff

}

这将对整个对象执行相同的功能。

回答3

https://stackoverflow.com/a/72294264/45375很好地解决了您的问题。

让我提供一个替代方案,它使用 PowerShell v5+ 自定义 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Classes 来为数组的实例建模,这使得对每个人的属性的访问更具描述性和类型安全:

# Define a [Person] class with a constructor that fills all properties.
class Person {
  [string] $Name
  [int]    $Age
  [char]   $Sex
  Person([string] $name, [int] $age, [char] $sex) { 
    $this.Name = $name; $this.Age = $age; $this.Sex = $sex
  }
}

# Create an array of [Person] instances.
$people = @(
 [Person]::new('adam', '24', 'M')
 [Person]::new('andy', '20', 'M')
 [Person]::new('alex', '30', 'M')
 [Person]::new('ava', '25', 'F')
)

# Filter the array via the .Where() array method.
$people.Where({ $_.Age -lt 25 -and $_.Sex -eq 'M' })

输出:

Name Age Sex
---- --- ---
adam  24   M
andy  20   M

如果您只对 .Name 属性 values 感兴趣,只需将 .Name 附加到上面的最后一个命令,该命令返回数组 'adam', 'andy',由 PowerShell 的 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Member-Access_Enumeration功能。

请注意 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Arrays#where 的使用,对于已在内存中的集合,该方法是 https://docs.microsoft.com/powershell/module/microsoft.powershell.core/where-object cmdlet 的更有效替代方法;也就是说,https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Foreach 表现最好。

相似文章