Powershell:筛选Hashtable-并获取Hastable

Tom*_*Tom 3 powershell hashtable

使用GetEnumerator过滤Hashtable总是返回一个object []而不是Hashtable:

# 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
Run Code Online (Sandbox Code Playgroud)

有解决这个问题的好方法吗?

非常感谢您的任何帮助!

bri*_*ist 7

$filtered是字典条目的数组。据我所知,没有任何一个演员或演员。

您可以通过以下方式构造哈希:

$hash = @{}
$filtered | ForEach-Object { $hash.Add($_.Key, $_.Value) }
Run Code Online (Sandbox Code Playgroud)

另一个工作流程:

# 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
Run Code Online (Sandbox Code Playgroud)

  • 您可能希望将$ items.Keys用$ @($ items.Keys)替换,以便在从集合中删除项目时不枚举集合。 (2认同)

Jus*_*ote 5

这是一个更简单的函数,它甚至具有包含和排除功能

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
}
Run Code Online (Sandbox Code Playgroud)

例子:

$testHashtable = @{a=1;b=2;c=3;d=4}

$testHashTable | Select-HashTable -Include a

Name                           Value
----                           -----
a                              1
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
$testHashTable | Select-HashTable -Include a,b,c -Exclude b


Name                           Value
----                           -----
a                              1
c                              3
Run Code Online (Sandbox Code Playgroud)