powershell - 查找哪个哈希表键值

powershell - find which hashtable key has value

我硬编码了一个哈希表

$myHash = @{
    Americas = "US","CA","MX" #,...
    Asia = "CN","JP" #,...
    Europe = "PL","GB" #,...you get the idea

现在我将在我设置

的 foreach 循环中遍历输入
$country = $_.country #The 2-letter country code

现在我想知道该国家/地区代码是否映射到美洲、亚洲或欧洲(也就是哪个键保存该值)。我怎样才能找到哪个键包含 2 个字母的国家代码,这样我就可以有一个 variable/output,它会说 AmericasAsiaEurope(即 $ myVar = ??? prints/outputs "America")。我不知道 powershell,所以我不知道完成此操作的具体语法

看起来 .containsValue() 适用于哈希表本身,而不是哈希表的键。我只有 3 个键,我只能有 3 个 if 语句

if($myHash["Americas"].containsValue()){ 
    $region = "Americas" 
    #or even better if I could get "Americas" dynamically by something like
    #$region = myHash.returnKeyThatContainsValue($country)
}
if($myHash["Asia"].containsValue()){...}
if($myHash["Europe"].containsValue()){...}

你可以这样做:

$myHash = @{
    Americas = "US","CA","MX" #,...
    Asia     = "CN","JP" #,...
    Europe   = "PL","GB"
}

foreach($key in $myHash.Keys){ 
    $value = $myHash[$key]
    foreach($val in $value){
        # if($val -eq "CN"){$key}
        Write-Host ("Key={0} Val={1}" -f $key,$val) -f Green
    }
}

更进一步,您可以将其变成 function,例如:

function ConvertFromCountryCode-ToFriendlyName
{
    param(
        [Parameter(Mandatory=$true)]
        [ValidateLength(2,2)] #edit: changed (0,2) to (2,2)
        [string]$CountryCode
    )

    $myHash = @{
        Americas = "US","CA","MX" #,...
        Asia     = "CN","JP" #,...
        Europe   = "PL","GB"
    }

    $outString = $null
    foreach($key in $myHash.Keys){ 
        $value = $myHash[$key]
        foreach($val in $value){
            if($val -eq $CountryCode){ 
                $outString = $key
                # added break to speed it up
                break
            }
        }
    }

    if($outString -eq $null){ 
        Write-Host "Currently our database does not contain a friendly name for that country." -f Red 
    } else { 
        $outString 
    }

}

它的用法如下:...

ConvertFromCountryCode-ToFriendlyName -CountryCode "US"

...并输出:

Americas
## Q:\Test18\SO_53126357.ps1
$myHash = @{
    Americas = "US","CA","MX" 
    Asia = "CN","JP"
    Europe = "PL","GB","DE"
}

## array to lookup
$countries = @("CN","GB","US")

## look up with .GetEnumerator() to find the value
Foreach ($Country in $Countries){
    [PSCustomObject]@{
        Country = $Country
        Continent = ($myHash.GetEnumerator()|Where-Object Value -eq $Country).Name
    }
}

Country Continent
------- ---------
CN      Asia
GB      Europe
US      Americas

## or build the reverse hash as it's meant to be ...
$HashMy = @{}
ForEach ( $Item in $myHash.GetEnumerator()){
    $Item.Value|ForEach-Object {$HashMy[$_] = $Item.Name }
}
$HashMy

Name Value
---- -----
CA   Americas
CN   Asia
DE   Europe
GB   Europe
JP   Asia
MX   Americas
PL   Europe
US   Americas

## get value by key
Foreach ($Country in $Countries){
    "{0} = {1}" -f $Country,$HashMy.$Country
}

CN = Asia
GB = Europe
US = Americas

我的错。我不知道你想要一个衬里..这是最简单的方法(我相信需要 PowerShell 5)

$myHash.GetEnumerator().Where({$_.Value -contains "US"})
#
Name                           Value                                                                                                                                     
----                           -----                                                                                                                                     
Americas                       {US, CA, MX}

如果你只想要名字:

$myHash.GetEnumerator().Where({$_.Value -contains "US"}).Name
#
Americas

"Old school"方式:

$myHash.GetEnumerator() | Where {$_.Value -contains "US"}