在哈希表数组中搜索键的最简洁方法

Most-succinct way to search an array of hash tables for a key

假设:

$columnArray = @(
  @{Name='COL_A';Type=[int];Measurements=@()},
  @{Name='COL_B';Type=[string];Measurements=@()},
  @{Name='COL_C';Type=[datetime];Measurements=@()}
)

使用 Where-Object 命令获取 COL_BMeasurements 数组:

($Fields | ? { $_.Name -eq 'COL_B' }).Measurements

有更简洁的方法吗?一组嵌套的 PSCustomObject 会是更好的方法吗?

您可以使用一种方法修改数组本身来进行查找:

Add-Member -InputObject $columnArray -MemberType ScriptMethod -Name FindCol -Value { param([String]$Column) $this | ? { $_.Name -eq $Column }  }

那么你可以这样做:

$columnArray.FindCol('COL_B').Measurements

或者你可以这样做:

Add-Member -InputObject $columnArray -MemberType ScriptMethod -Name GetMeasurements -Value { param([String]$Column) $this | ? { $_.Name -eq $Column } | Select-Object -ExpandProperty Measurements  }

然后:

$columnArray.GetMeasurements('COL_B')

如果您有兴趣逐个查找元素,Hashtable 比数组更好。

$columnHashtable=@{
    COL_A=@{Type=[int];Measurements=@()}
    COL_B=@{Type=[string];Measurements=@()}
    COL_C=@{Type=[datetime];Measurements=@()}
}

使用 Hashtable 您可以通过以下命令获得 MeasurementsCOL_B 数组:

$columnHashtable.COL_B.Measurements

而如果你想枚举Hashtable中的所有元素,那么你可以使用以下命令:

$columnHashtable.GetEnumerator()|ForEach-Object ...

如果散列 table 中元素的顺序很重要,您可以在散列 table 文字之前使用 [ordered] 运算符来创建 OrderedDictionary 而不是 Hashtable.

如果你采用这种方法:

$Info = [PSCustomObject]@{
  Name = "MyFieldName"
  Size = 15
  Date = Get-Date
}

那么这些都有效:

 $Info | Select Name, Size 
 $Info | Where ($_.date -gt (Get-Date).AddDays(-1)) 
 $Info | Sort Size -Descending | Select -First 1

您还可以将用于填充数据的任何函数放入 $Info。

$results = Import-CSV C:\Results.csv 

$items =  Foreach ($item in $results) {
   $thisItem = [PSCustomObject]@{
   Name = $_.name
   Size = $_.size
   Date = $_.date
   }
   $thisItem
}

这个怎么样:

$columnArray | % {New-Object PSObject -property $_} | ? {$_.Name -eq 'COL_B'} | Select -ExpandProperty Measurements

它使用 -property 标志将数组的每个元素转换为一个对象,这样就不必显式定义对象或使用 Add-Member