powershell-查找哪个哈希表键具有值

时间:2018-11-02 22:05:34

标签: powershell hashtable

我对哈希表进行了硬编码

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

现在我要在设置的foreach循环中通过输入

$country = $_.country #The 2-letter country code

现在,我想查找该国家/地区代码是否映射到美洲,亚洲或欧洲(也就是哪个键具有该值)。如何找到哪个键包含2个字母的国家/地区代码,这样我就可以拥有一个变量/输出,显示AmericasAsiaEurope(即$ myVar = ???打印/输出“美国”)。我不知道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()){...}

3 个答案:

答案 0 :(得分:1)

## Q:\Test\2018\11\02\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

答案 1 :(得分:1)

我的错。我不知道您是否需要一个衬板。这是最简单的方法(我相信需要PowerShell 5)

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

如果您只想要名称:

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

“老派”方式:

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

答案 2 :(得分:0)

您可以执行以下操作:

$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