tablas estructura datos powershell hashtable

powershell - estructura - tablas hash c++



¿Cómo puedo enumerar una tabla hash como pares clave-valor/filtrar una tabla hash por una colección de valores clave? (2)

Nota del editor: esta pregunta tiene una historia complicada, pero se reduce a esto:
* Para saber cómo enumerar las entradas de una tabla hash por sus pares clave-valor , vea la respuesta aceptada .
* Para aprender a filtrar una tabla hash por una colección de valores clave , vea la otra respuesta .

Creo que volví a caer en el problema XY, mi pregunta inicial era sobre Filtrar una tabla hash. Descubrí que es más fácil filtrar antes de crear la tabla hash. Pregunta respondida, ¿verdad?

No, el problema de la Y estaba enlazando cada clave y usando los valores con los que @briantist me ayudó.

Mi objetivo es recorrer los nombres de las claves, que son marcas de tiempo, y programar una tarea utilizando el nombre de la clave como el nombre de la tarea y el activador.

Estoy creando una tabla hash a partir de un archivo CSV usando Group-Object -AsHashTable -AsString -edit, vale la pena mencionar aquí que filtrar el CSV antes de crear el HashTable solo facilita las cosas en Pipeline o script .

Como ejemplo:

Import-CSV (ls -path D:/ -Filter source*.csv | sort LastWriteTime | Select -Last 1).FullName | where {$_.TimeCorrected -ne ''ManualRebootServer''} | group TimeCorrected -AsHashTable -AsString

Estoy intentando pasar los nombres de las teclas y puedo mostrar los nombres de las teclas usando:

$var = Import-Csv csv123.csv | Group-Object Value1 -AsHashTable -AsString foreach ($key in $var.Keys){"The key name is $key"} #Create a scheduled task named and triggered based on the HashTable keyname #test test test foreach ($key in $var.keys){IF($key -ne ''ManualRebootServer''){"Register-ScheduledJob"}}

Simplemente no estoy seguro de cómo obtener los valores de las claves que me interesan.

He encontrado los siguientes trabajos, pero solo cuando ingreso un Nombre de clave manualmente. Simplemente no estoy seguro de cómo combinar ambos bucles.

($val.GetEnumerator() | Where {$_.key -eq ''06-11-16 18:00''} | ForEach-Object { $_.value }).Server


Para complementar la útil respuesta del briantista, enfóquese en filtrar una tabla hash mediante una matriz de valores clave (sintaxis de PSv3 +):

# Sample hashtable. $ht = @{ one = 1; two = 2; three = 3 } # Filter it by an array of key values; applying .GetEnumerator() yields an array # of [System.Collections.DictionaryEntry] instances, which have # a .Key property and a .Value property. $ht.GetEnumerator() | ? Key -in ''one'', ''two'' # Similarly, the *output* - even though it *looks* like a hashtable - # is a regular PS *array* ([Object[]]) containing [System.Collections.DictionaryEntry] # entries (2 in this case). $arrFilteredEntries = $ht.GetEnumerator() | ? Key -in ''one'', ''two'' $arrFilteredEntries.GetType().Name # -> Object[]

Para seguir procesando los pares clave-valor coincidentes , simplemente ForEach-Object a % ( ForEach-Object ) y acceda a $_.Key y $_.Value (valor):

$ht.GetEnumerator() | ? Key -in ''one'', ''two'' | % { "Value for key ''$($_.Key)'': $($_.Value)" }

El comando equivalente que usa un bucle foreach más eficiente en lugar de la tubería:

foreach ($key in $ht.Keys) { if ($key -in ''one'', ''two'') { "Value for key ''$($key)'': $($ht.$key)" } }

Nota: En PSv2 :
* operator -in no es compatible, pero puede usar -contains cambio con los operandos intercambiados :
''one'', ''two'' -contains $key
* en la tubería, use Where-Object { ''one'', ''two'' -contains $_.Key }

Con la muestra hashtable, esto produce:

Value for key ''two'': 2 Value for key ''one'': 1

Observe cómo el orden de clave en la salida difiere del orden de definición; en PSv3 +, puede crear tablas hash ordenadas ( [ordered] @{ ... } ) para conservar el orden de definición.

La técnica de filtrado de claves utilizada anteriormente no se limita al filtrado por matrices de claves literales ; cualquier colección (cadena) funcionará como el RHS del operando -in , como la colección .Keys de una tabla hash diferente :

# Sample input hashtable. $htInput = @{ one = 1; two = 2; three = 3 } # Hashtable by whose keys the input hashtable should be filtered. # Note that the entries'' *values* are irrelevant here. $htFilterKeys = @{ one = $null; two = $null } # Perform filtering. $htInput.GetEnumerator() | ? Key -in $htFilterKeys.Keys | % { "Value for key ''$($_.Key)'': $($_.Value)" } # `foreach` loop equivalent: foreach ($key in $htInput.Keys) { if ($key -in $htFilterKeys.Keys) { "Value for key ''$($key)'': $($htInput.$key)" } }

El resultado es el mismo que en el ejemplo con la matriz de claves de filtro estáticas.

Finalmente, si desea filtrar una tabla hash en su lugar o crear una tabla hash nueva con solo las entradas filtradas :

# *In-place* Updating of the hashtable. # Remove entries other than the ones matching the specified keys. # Note: The @(...) around $ht.Keys is needed to clone the keys collection before # enumeration, so that you don''t get an error about modifying a collection # while it is being enumerated. foreach ($key in @($ht.Keys)) { if ($key -notin ''one'', ''two'') { $ht.Remove($key) } } # Create a *new* hashtable with only the filtered entries. # By accessing the original''s .Keys collection, the need for @(...) is obviated. $htNew = $ht.Clone() foreach ($key in $ht.Keys) { if ($key -notin ''one'', ''two'') { $htNew.Remove($key) } }

Como un aparte:

El formato de salida predeterminado para [System.Collections.DictionaryEntry] (y, por lo tanto, hashtables ( [System.Collections.Hashtable] ) utiliza el nombre de la columna en lugar de la Key ; el Name se define como una propiedad de alias de la Key agregada por PowerShell (no es parte de la definición de tipo .NET [System.Collections.DictionaryEntry] ; verifique con
@{ one = 1 }.GetEnumerator() | Get-Member @{ one = 1 }.GetEnumerator() | Get-Member ).


Tienes algunas opciones aquí.

Enumerar a través de las teclas:

foreach ($key in $var.Keys) { $value = $var[$key] # or $value = $var.$key }

Enumerar pares clave-valor (que ha descubierto, pero puede que no se estén usando de manera efectiva):

foreach ($kvp in $var.GetEnumerator()) { $key = $kvp.Key $val = $kvp.Value }