在哈希表数组中搜索键的最简洁方法
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_B
的 Measurements
数组:
($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
您可以通过以下命令获得 Measurements
个 COL_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
假设:
$columnArray = @(
@{Name='COL_A';Type=[int];Measurements=@()},
@{Name='COL_B';Type=[string];Measurements=@()},
@{Name='COL_C';Type=[datetime];Measurements=@()}
)
使用 Where-Object
命令获取 COL_B
的 Measurements
数组:
($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
您可以通过以下命令获得 Measurements
个 COL_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