使用 GetEnumerator 过滤哈希表总是返回一个对象 [] 而不是哈希表:
# Init Hashtable
$items = @{ a1 = 1; a2 = 2; b1 = 3; b2 = 4}
# apply a filter
$filtered = $items.GetEnumerator() | ?{ $_.Key -match "a.*" }
# The result looks great
$filtered
Name Value
---- -----
a2 2
a1 1
# … but it is not a Hashtable :-(
$filtered.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
这个问题有好的解决方案吗?
非常感谢您的帮助! 亲切的问候, 汤姆
$filtered
是字典条目的数组。据我所知,没有单一的演员或演员。
虽然你可以构造一个散列:
$hash = @{}
$filtered | ForEach-Object { $hash.Add($_.Key, $_.Value) }
另一个工作流程:
# Init Hashtable
$items = @{ a1 = 1; a2 = 2; b1 = 3; b2 = 4}
# Copy keys to an array to avoid enumerating them directly on the hashtable
$keys = @($items.Keys)
# Remove elements not matching the expected pattern
$keys | ForEach-Object {
if ($_ -notmatch "a.*") {
$items.Remove($_)
}
}
# $items is filtered
这是一个更简单的函数,它甚至具有包含和排除功能
function Select-HashTable {
[CmdletBinding()]
param (
[Parameter(Mandatory,ValueFromPipeline)][Hashtable]$Hashtable,
[String[]]$Include = ($HashTable.Keys),
[String[]]$Exclude
)
if (-not $Include) {$Include = $HashTable.Keys}
$filteredHashTable = @{}
$HashTable.keys.where{
$PSItem -in $Include
}.where{
$PSItem -notin $Exclude
}.foreach{
$filteredHashTable[$PSItem] = $HashTable[$PSItem]
}
return $FilteredHashTable
}
例子:
$testHashtable = @{a=1;b=2;c=3;d=4}
$testHashTable | Select-HashTable -Include a
Name Value
---- -----
a 1
$testHashTable | Select-HashTable -Exclude b
Name Value
---- -----
c 3
d 4
a 1
$testHashTable | Select-HashTable -Include a,b,c -Exclude b
Name Value
---- -----
a 1
c 3
由于接受的答案导致我出现
BadEnumeration
异常(但仍然有效),我修改它以不抛出异常并且还确保原始HashTable
没有通过首先克隆它来修改:
# Init Hashtable
$items = @{ a1 = 1; a2 = 2; b1 = 3; b2 = 4}
$filtered = $items.Clone()
$items.Keys | ForEach-Object {
if ($_ -notmatch "a.*") {
$filtered.Remove($_)
}
}
在现代
PowerShell
(据我记得5
+)你可以使用reduce
模式。为此,您需要使用这种形式的ForEach-Object
:
$Hashtable.Keys
| ForEach-Object -Begin {
$FilteredHashtable = @{}
} -Process {
if ($_ -eq 'Example') {
$FilteredHashtable[$_] = $Hashtable[$_];
}
} -End {
$FilteredHashtable
}
是的,这个片段将返回
Hashtable
.