2012-07-06 6 views
7

Ho una tabella hash in cui vengono utilizzate le chiavi in ​​base al valore.Come ottenere hash table key che ha un valore specifico?

Per es.

[email protected]{"ComponentNameX"="True"; 
          "ComponentNameXyz"="False"; 
          "SomeComponent"="False"} 

Vorrei ottenere le chiavi che hanno valori True. (Passerò la chiave ad un altro script come parametro).

Stavo provando in questo modo, ma penso che alcuni mi manchi perché non elenca le chiavi.

$($ComponentToBuild.Keys) | Where-Object { $_.Value -eq "True" } 

Come ottenere il componente Nome che ha indicato come True? Inoltre vorrei sapere se il tavolo hash è una scelta saggia per questo tipo di lavoro. Perché pensavo che la tabella di hash verrà utilizzata principalmente per elaborare i valori.

risposta

8

Ciao questo dovrebbe funzionare per quello che vuoi.

[email protected]{"ComponentNameX"="Test"; 
          "ComponentNameXyz"="False"; 
          "SomeComponent"="False"}      

Foreach ($Key in ($ComponentTobeBuild.GetEnumerator() | Where-Object {$_.Value -eq "Test"})) 
{$Key.name} 
+0

Questo script sta cercando di ottenere valori, in realtà stavo cercando di ottenere le chiavi. Ma anche questo non funziona. $ ComponentTobeBuild.Keys | Where-Object {$ _ -eq "True"} – Samselvaprabu

+0

O ok scusa ho cambiato il controllo del codice se funziona ora.ps copia il codice completo e provalo, puoi inserire il codice nella sezione "{$ Key.name}" per mettere tutte le chiavi che hanno un valore di test in un'altra tabella hash, se lo desideri – justinf

11
$ComponentTobeBuild.GetEnumerator() | ?{ $_.Value -eq "True" } 
6

So che questo è vecchio, ma ho trovato questo su mia ricerca di un altro problema e si chiese perché vi preoccupate con Enumerators. Basta compilare il codice esattamente come la domanda nella lingua reale:

Dammi tutte le chiavi, dove il valore è 'True'.

$ComponentTobeBuild.Keys | ? { $ComponentTobeBuild[$_] -eq 'True' } 

Per motivi di coerenza avrei incapsulare che in @() per ottenere un array anche se c'è solo uno o nessun risultato.

Per quanto riguarda la Soluzione che il richiedente ha avuto, il problema è che $_ è una stringa e .Value non è il valore della chiave. Semplicemente non esiste in una stringa. È necessario ottenere il valore della tabella hash con $_ come chiave per poterlo confrontare.

+0

Ciò potrebbe causare imprevisti comportamento quando la raccolta ha più voci con la stessa chiave ... –

+0

@ oɔɯǝɹ in PowerShell non è possibile creare hastable con chiavi non univoche – maoizm

+0

@maozim Penso che stiamo usando il termine hashtable in modo errato, dal momento che stiamo usando un dizionario/mappa nella domanda. Gli hashtables in .net possono avere collisioni e utilizzeranno un elenco collegato per memorizzare più elementi con lo stesso codice hash. Un hashtable è tutto sul recupero per oggetto. Un dizionario utilizza le chiavi univoche –

3

Il problema con il filtro di hashtables in PowerShell è che non è possibile eseguire iterazioni sulle coppie chiave-valore.

Diciamo che avete un po 'di raccolta:

$collection = @{ 
    a = 'A'; 
    b = 'B'; 
    c = 'C'; 
    d = 'D'; 
    e = 'E'; 
    ... 
} 

ci si aspetta di essere in grado di utilizzare

$results = $collection | Where-Object { $_.Key -in ('a', 'b', 'd') } 

in PowerShell, ma questo non è possibile.

Pertanto è necessario ripiegare a utilizzare l'enumeratore:

$results = $collection.GetEnumerator() | Where-Object { $_.Key -in ('a', 'b', 'd') } 
$results 

Name       Value 
----       ----- 
d        D 
b        B 
a        A 
+0

Qualcuno può fornire una spiegazione logica perché .keys non può essere iterato o indicizzato come altre raccolte? Il suo tipo è Hashtable + keyCollection, che almeno implica che è una sorta di collezione. – BobHy

0

Si potrebbe anche utilizzare il 'metodo di WhereDictionary.Keys che restituisce tutti gli elementi in cui una condizione vale. Tale condizione potrebbe essere una lambda che asserisce che la chiave testata $_ si riferisce a un valore "True" nel dizionario.

[email protected]{"ComponentNameX"="True"; 
         "ComponentNameXyz"="False"; 
         "SomeComponent"="False"} 
$ComponentTobeBuild.Keys.Where({$ComponentTobeBuild[$_] -eq "True"}) 
# -> @("ComponentNameX")