Compartir a través de


about_Hash_Tables

Descripción breve

Describe cómo crear, usar y ordenar tablas hash en PowerShell.

Descripción larga

Una hashtable, también conocida como diccionario o matriz asociativa, es una estructura de datos compacta que almacena uno o más pares clave-valor. Por ejemplo, una tabla hash puede contener una serie de direcciones IP y nombres de equipo, donde las direcciones IP son las claves y los nombres de equipo son los valores, o viceversa.

En PowerShell, cada hashtable es un objeto [System.Collections.Hashtable]. Puede usar las propiedades y los métodos de Hashtable objetos en PowerShell.

A partir de PowerShell 3.0, puede usar el [ordered] acelerador de tipos para crear un [System.Collections.Specialized.OrderedDictionary] objeto en PowerShell.

Los diccionarios ordenados difieren de las tablas hash en que las claves siempre aparecen en el orden en que se enumeran. El orden de las claves en una hashtable no es determinista.

Las claves y el valor de las tablas hash también son objetos .NET. Suelen ser cadenas o enteros, pero pueden tener cualquier tipo de objeto. También se pueden crear hashtables anidadas, en las que el valor de una clave es otra hashtable.

Las tablas hash se usan con frecuencia porque son eficaces para buscar y recuperar datos. Puede usar tablas hash para almacenar listas y crear propiedades calculadas en PowerShell. Además, el cmdlet ConvertFrom-StringData convierte datos de cadena estructurados en una hashtable.

Sintaxis

La sintaxis de una hashtable es la siguiente:

@{ <name> = <value>; [<name> = <value> ] ...}

La sintaxis de un diccionario ordenado es la siguiente:

[ordered]@{ <name> = <value>; [<name> = <value> ] ...}

El [ordered] acelerador de tipos se introdujo en PowerShell 3.0.

Para crear una hashtable, siga estas directrices:

  • Comience la tabla hash con el signo (@).
  • Incluya la tabla hash entre llaves ({}).
  • Escriba uno o varios pares clave-valor para el contenido de la tabla hash.
  • Use un signo igual (=) para separar cada clave de su valor.
  • Use un punto y coma (;) o un salto de línea para separar los pares clave-valor.
  • Las claves que contienen espacios deben incluirse entre comillas. Los valores deben ser expresiones de PowerShell válidas. Las cadenas deben aparecer entre comillas, aunque no incluyan espacios.
  • Para administrar la hashtable, guárdela en una variable.
  • Al asignar una tabla hash ordenada a una variable, coloque el tipo [ordered] antes del símbolo @. Si lo coloca antes del nombre de la variable, se produce un error en el comando.

Puede usar diccionarios ordenados de la misma manera que se usan tablas hash. Cualquiera de los tipos se puede usar como valor de los parámetros que aceptan objetos de tipo tabla hash o diccionario (iDictionary).

Creación de tablas hash y diccionarios ordenados

Tenga en cuenta los siguientes ejemplos de tabla hash y de diccionario ordenado:

$hash = @{
    1       = 'one'
    2       = 'two'
    'three' = 3
}
$hash
Name                           Value
----                           -----
three                          3
2                              two
1                              one

Como puede ver, los pares clave-valor de una hashtable no se presentan en el orden en que se definieron.

La manera más fácil de crear un diccionario ordenado es usar el [ordered] atributo . Coloque el atributo inmediatamente antes del @ símbolo.

$dictionary = [ordered]@{
    1       = 'one'
    2       = 'two'
    'three' = 3
}
$dictionary
Name                           Value
----                           -----
1                              one
2                              two
three                          3

A diferencia de las tablas hash, los diccionarios ordenados mantienen el orden del valor de clave.

Conversión de tablas hash y diccionarios ordenados

No puede usar el acelerador de tipos [ordered] para convertir o transformar una tabla hash. Si coloca el atributo ordenado antes del nombre de la variable, se produce un error en el comando con el siguiente mensaje de error.

[ordered]$orderedhash = @{}
ParserError:
Line |
   1 |  [ordered]$orderedhash = @{}
     |  ~~~~~~~~~~~~~~
     | The ordered attribute can be specified only on a hash literal node.

Para corregir la expresión, mueva el atributo [ordenado].

$orderedhash = [ordered]@{}

Puede convertir un diccionario ordenado en una tabla hash, pero no puede garantizar el orden de los miembros.

[hashtable]$newhash = [ordered]@{
    Number = 1
    Shape = "Square"
    Color = "Blue"
}
$newhash
Name                           Value
----                           -----
Color                          Blue
Shape                          Square
Number                         1

Hashtable propiedades de diccionario y

Las tablas hash y los diccionarios ordenados comparten varias propiedades. Tenga en cuenta las $hash variables y $dictionary definidas en los ejemplos anteriores.

$hash | Get-Member -MemberType Properties, ParameterizedProperty
   TypeName: System.Collections.Hashtable

Name           MemberType            Definition
----           ----------            ----------
Item           ParameterizedProperty System.Object Item(System.Object key) {get;set;}
Count          Property              int Count {get;}
IsFixedSize    Property              bool IsFixedSize {get;}
IsReadOnly     Property              bool IsReadOnly {get;}
IsSynchronized Property              bool IsSynchronized {get;}
Keys           Property              System.Collections.ICollection Keys {get;}
SyncRoot       Property              System.Object SyncRoot {get;}
Values         Property              System.Collections.ICollection Values {get;}
$dictionary | Get-Member -MemberType Properties, ParameterizedProperty
   TypeName: System.Collections.Specialized.OrderedDictionary

Name           MemberType            Definition
----           ----------            ----------
Item           ParameterizedProperty System.Object Item(int index) {get;set;},
                                     System.Object Item(System.Object key) {get;set;}
Count          Property              int Count {get;}
IsFixedSize    Property              bool IsFixedSize {get;}
IsReadOnly     Property              bool IsReadOnly {get;}
IsSynchronized Property              bool IsSynchronized {get;}
Keys           Property              System.Collections.ICollection Keys {get;}
SyncRoot       Property              System.Object SyncRoot {get;}
Values         Property              System.Collections.ICollection Values {get;}

Las propiedades más usadas son Count, Keys, Values y Item.

  • Propiedad Count que indica el número de pares clave-valor del objeto.

  • La propiedad Keys es una colección de los nombres de clave en la tabla hash o el diccionario.

    PS> $hash.Keys
    three
    2
    1
    
    PS> $dictionary.Keys
    1
    2
    three
    
  • La propiedad Values es una colección de los valores de la tabla hash o del diccionario.

    PS> $hash.Values
    3
    two
    one
    
    PS> $dictionary.Values
    one
    two
    3
    
  • La propiedad Item es una propiedad parametrizada que devuelve el valor del elemento que especifique. Las tablas hash usan la clave como parámetro para la propiedad parametrizada, mientras que los diccionarios usan el índice de forma predeterminada. Esta diferencia afecta a cómo se accede a los valores de cada tipo.

Acceso a valores

Hay dos formas comunes de acceder a los valores de una tabla hash o diccionario: notación de miembros o notación de índice de matriz.

  • Notación de miembro: se puede tener acceso a los valores mediante el nombre de clave como una propiedad miembro del objeto. Por ejemplo:

    PS> $hash.1
    one
    
    PS> $dictionary.2
    two
    
  • Notación de índice de matriz : se puede tener acceso a los valores mediante la notación de índice. PowerShell convierte esa notación en una llamada a la propiedad parametrizada Item del objeto .

    Cuando se usa la notación de índice con tablas hash, el valor dentro de los corchetes es el nombre de clave. Si la clave es un valor de cadena, escriba el nombre de clave entre comillas. Por ejemplo:

    PS> $hash['three']
    3
    
    PS> $hash[2]
    two
    

    En este ejemplo, el valor 2 de clave no es un índice en la colección de valores. Es el valor de la clave en el par clave-valor. Puede probarlo indizando en la colección de valores.

    PS> ([array]$hash.Values)[2]
    one
    

    Cuando se usa la notación de índice con diccionarios, el valor dentro de los corchetes se interpreta en función de su tipo. Si el valor es un entero, se trata como un índice en la colección de valores. Si el valor no es un entero, se trata como nombre de clave. Por ejemplo:

    PS> $dictionary[1]
    two
    PS> ([array]$dictionary.Values)[1]
    two
    PS> $dictionary[[object]1]
    one
    PS> $dictionary['three']
    3
    

    En este ejemplo, el valor [1] de matriz es un índice en la colección de valores mediante la sobrecarga de la Item(int index) propiedad parametrizada. El valor [[object]1] de la matriz no es un índice, sino un valor de clave mediante la Item(System.Object key) sobrecarga.

    Nota:

    Este comportamiento puede resultar confuso cuando el valor de clave es un entero. Siempre que sea posible, debe evitar el uso de valores de clave enteros en diccionarios.

Control de colisiones de nombres de propiedad

Si el nombre de clave entra en conflicto con uno de los nombres de propiedad del tipo Hashtable, puede usar el miembro intrínsecopsbase para acceder a esas propiedades. Por ejemplo, si el nombre de la clave es keys y desea devolver la colección de las claves HashTable, utilice esta sintaxis:

$hashtable.psbase.Keys

Este requisito se aplica a otros tipos que implementan la System.Collections.IDictionary interfaz, como OrderedDictionary.

Iteración de claves y valores

Puede recorrer las claves de una tabla hash para procesar los valores de diferentes formas. Cada uno de los ejemplos de esta sección tiene una salida idéntica. Recorren en iteración la $hash variable definida aquí:

$hash = [ordered]@{Number = 1; Shape = "Square"; Color = "Blue"}

Nota:

En estos ejemplos, $hash se define como un diccionario ordenado para asegurarse de que la salida siempre está en el mismo orden. Estos ejemplos funcionan igual para tablas hash estándar, pero el orden de la salida no es predecible.

Cada ejemplo devuelve un mensaje para cada clave y su valor:

The value of 'Number' is: 1
The value of 'Shape' is: Square
The value of 'Color' is: Blue

En este ejemplo se usa un foreach bloque para iterar las claves.

foreach ($Key in $hash.Keys) {
    "The value of '$Key' is: $($hash[$Key])"
}

En este ejemplo se usa ForEach-Object para iterar las claves.

$hash.Keys | ForEach-Object {
    "The value of '$_' is: $($hash[$_])"
}

En este ejemplo se usa el GetEnumerator() método para enviar cada par clave-valor a través de la canalización a ForEach-Object.

$hash.GetEnumerator() | ForEach-Object {
    "The value of '$($_.Key)' is: $($_.Value)"
}

En este ejemplo se usan los GetEnumerator() métodos y ForEach() para iterar en cada par clave-valor.

$hash.GetEnumerator().ForEach({"The value of '$($_.Key)' is: $($_.Value)"})

Agregar y quitar claves y valores

Normalmente, cuando se crea una hashtable se incluyen los pares clave-valor en la definición. Sin embargo, puede añadir y eliminar pares clave-valor de una tabla hash en cualquier momento. El siguiente ejemplo crea una tabla hash vacía.

$hash = @{}

Puede agregar pares clave-valor mediante la notación de matriz. El siguiente ejemplo añade una clave Time con un valor Now de a la tabla hash.

$hash["Time"] = "Now"

También puede añadir claves y valores a una hashtable utilizando el método Add() del objeto System.Collections.Hashtable. El método Add() tiene la siguiente sintaxis:

Add(Key, Value)

Por ejemplo, para añadir una clave Time con un valor de Now a la tabla hash, utilice el siguiente formato de instrucción.

$hash.Add("Time", "Now")

Además, puede añadir claves y valores a una tabla hash utilizando el operador de adición (+) para añadir una tabla hash a una tabla hash existente. Por ejemplo, la siguiente instrucción añade una clave Time con un valor de Now a la tabla hash de la variable $hash.

$hash = $hash + @{Time="Now"}

También puede agregar valores almacenados en variables.

$t = "Today"
$now = (Get-Date)

$hash.Add($t, $now)

No se puede utilizar un operador de sustracción para eliminar un par clave-valor de una tabla hash, pero se puede utilizar el método Remove() del objeto de la tabla hash. El método Remove tiene la siguiente sintaxis:

$object.Remove(<key>)

En el ejemplo siguiente se quita el Time par clave-valor de $hash.

$hash.Remove("Time")

Tipos de objeto en HashTables

Las claves y valores de una tabla hash pueden tener cualquier tipo de objeto .NET, y una misma tabla hash puede tener claves y valores de varios tipos.

La siguiente instrucción crea una tabla hash de cadenas de nombre de proceso y valores de objeto de proceso y la guarda en la variable $p.

$p = @{
    "PowerShell" = (Get-Process PowerShell)
    "Notepad" = (Get-Process notepad)
}

Puede mostrar la hashtable en $p y utilizar las propiedades clave-nombre para mostrar los valores.

PS> $p

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (PowerShell)
Notepad                        System.Diagnostics.Process (notepad)

PS> $p.PowerShell

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    441      24    54196      54012   571     5.10   1788 PowerShell

PS> $p.Keys | ForEach-Object {$p.$_.Handles}
441
251

Las claves de una hashtable pueden ser de cualquier tipo .NET. La siguiente instrucción añade un par clave-valor a la tabla hash en la variable $p. La clave es un objeto Service que representa el servicio WinRM y el valor es el estado actual del servicio.

$p = $p + @{
    (Get-Service WinRM) = ((Get-Service WinRM).Status)
}

Puede visualizar y acceder al nuevo par clave-valor utilizando los mismos métodos que utiliza para otros pares de la tabla hash.

PS> $p

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (PowerShell)
Notepad                        System.Diagnostics.Process (notepad)
System.ServiceProcess.Servi... Running

PS> $p.Keys
PowerShell
Notepad

Status   Name               DisplayName
------   ----               -----------
Running  winrm              Windows Remote Management (WS-Manag...

PS> $p.Keys | ForEach-Object {$_.Name}
WinRM

Las claves y los valores de una tabla hash también pueden ser objetos Hashtable. La siguiente instrucción añade un par clave-valor a la hashtable en la variable $p en la que la clave es una cadena, Hash2, y el valor es una hashtable con tres pares clave-valor.

$p = $p + @{
    "Hash2"= @{a=1; b=2; c=3}
}

Puede mostrar y acceder a los nuevos valores mediante los mismos métodos.

PS> $p

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (pwsh)
Hash2                          {[a, 1], [b, 2], [c, 3]}
Notepad                        System.Diagnostics.Process (Notepad)
WinRM                          Running

PS> $p.Hash2

Name                           Value
----                           -----
a                              1
b                              2
c                              3

PS> $p.Hash2.b
2

Ordenar claves y valores

Los elementos de una tabla hash están intrínsecamente desordenados. Los pares clave-valor pueden aparecer en un orden diferente cada vez que los muestre.

Aunque no puede ordenar una hashtable, puede utilizar el método GetEnumerator() de tablas hash para enumerar las claves y los valores y, a continuación, utilizar el cmdlet Sort-Object para ordenar los valores enumerados para su visualización.

Por ejemplo, los siguientes comandos enumeran las claves y los valores de la tabla hash de la $p variable y, a continuación, ordenan las claves en orden alfabético.

PS> $p.GetEnumerator() | Sort-Object -Property key

Name                           Value
----                           -----
Hash2                          {[a, 1], [b, 2], [c, 3]}
Notepad                        System.Diagnostics.Process (Notepad)
PowerShell                     System.Diagnostics.Process (pwsh)
WinRM                          Running

El comando siguiente usa el mismo procedimiento para ordenar los valores hash en orden descendente.

PS> $p.GetEnumerator() | Sort-Object -Property Value -Descending

Name                           Value
----                           -----
PowerShell                     System.Diagnostics.Process (pwsh)
Notepad                        System.Diagnostics.Process (Notepad)
Hash2                          {[a, 1], [b, 2], [c, 3]}
WinRM                          Running

Creación de objetos a partir de tablas hash

A partir de PowerShell 3.0, puede crear un objeto a partir de una tabla hash de propiedades y valores de propiedades.

La sintaxis es la siguiente:

[<class-name>]@{
  <property-name>=<property-value>
  <property-name>=<property-value>
}

Este método solo funciona para las clases que tienen un constructor que no tiene parámetros. Las propiedades del objeto deben ser públicas y configurables.

Para obtener más información, consulte about_Object_Creation.

ConvertFrom-StringData

El cmdlet ConvertFrom-StringData convierte una cadena o una cadena de tipo "here-string" de pares clave-valor en una tabla hash. Puede usar el ConvertFrom-StringData cmdlet de forma segura en la sección Datos de un script y puede usarlo con el Import-LocalizedData cmdlet para mostrar los mensajes de usuario en la referencia cultural de la interfaz de usuario (UI) del usuario actual.

Las cadenas de tipo "here-strings" son especialmente útiles cuando los valores de la tabla hash incluyen comillas. Para obtener más información sobre las cadenas aquí, consulte about_Quoting_Rules.

El siguiente ejemplo muestra cómo crear una cadena here de los mensajes de usuario del ejemplo anterior y cómo utilizar ConvertFrom-StringData para convertirlos de una cadena a una tabla hash.

El siguiente comando crea una cadena aquí de los pares clave-valor y, a continuación, la guarda en la $string variable .

$string = @"
Msg1 = Type "Windows".
Msg2 = She said, "Hello, World."
Msg3 = Enter an alias (or "nickname").
"@

Este comando utiliza el cmdlet ConvertFrom-StringData para convertir el here-string en un tabla hash.

ConvertFrom-StringData $string

Name                           Value
----                           -----
Msg3                           Enter an alias (or "nickname").
Msg2                           She said, "Hello, World."
Msg1                           Type "Windows".

Para obtener más información sobre las cadenas aquí, consulte about_Quoting_Rules.

Consulte también