Arrays y diccionarios en PowerShell

PowerShell

Este es uno de los capítulos del tutorial PowerShell. Encontrarás los enlaces a todos los de capítulos, al final de este artículo.

En el capítulo anterior del tutorial sobre variables en PowerShell, nos dejamos dos tipos de variables muy, pero que muy interesantes. Y no es que las dejara por olvido, si no todo lo contrario, las dejé porque se trata de dos tipos de variables, muy especiales, a las que es necesario dedicarles mas atención y cariño, por las características que tienen. Se trata de los arrays y diccionarios en PowerShell.

Se trata de dos tipos de variables, que al contrario que las que viste anteriormente, pueden contener mas de un elemento. Por ejemplo, el resultado de ejecutar el cmdlet Get-Process, devuelve un array de objetos que contiene cada uno de los procesos que se están ejecutando en tu sistema.

Así, en este capítulo del tutorial, trabajaremos sobre array y diccionarios en PowerShell*, viendo las características de cada uno de estos dos tipos de variables, y las ventajas de tratar con estos tipos.

Arrays y diccionarios en PowerShell

Arrays y diccionarios en PowerShell

Empezaré primero con los arrays que son algo mas intuitivos que los diccionarios, pero no por ello pienses, que ninguno de estos son realmente complejos.

Arrays en PowerShell

¿Que es un array en PowerShell?

Un array en PowerShell, como en otros lenguajes de programación, no es mas que un conjunto de elementos, elementos seguidos uno de otro, lo que normalmente conoces como una lista. Como por ejemplo, la mas conocida de las listas que es La lista de la compra.

Así, en tu lista de la compra, tienes un conjunto de productos, al igual que sucede con un array.

Crear un array en PowerShell

Además de que algunos cmdlet te devuelven arrays, tu también tienes la posibilidad de crear tus propios arrays para tratar de forma mas sencilla y eficaz un conjunto de elementos. Así para crear un array vacío, puedes hacerlo de la siguiente forma,

$a = @()

Indicarte que un array es un objeto en PowerShell, y como objeto que es tiene una serie de propiedades y de métodos. Por ejemplo, puedes conocer el número de elementos de un array, utilizando la propiedad Count, como en el siguiente ejemplo,

Otra forma sencilla, pero a la vez muy útil de crear un array en PowerShell es como te muestro en el siguiente ejemplo,

PS> $array = 1..3
PS> Write-Output $array
1
2
3
Write-Output $a.Count

Que dado que has creado un array vacío te devolverá 0, como no puede ser de otra forma.

Antes de continuar, hacerte una importante observación, y es que los arrays tienen un tamaño fijo. Es decir, un array no puede crecer, si lo has definido con cero elementos, tu array será un array vacío durante toda su existencia. Si quieres, una colección que tenga similares propiedades a las de un array, pero que además crezca, como tu lista de la compra, tendrás que utilizar un ArrayList.

Otras opciones que tienes para crear un array, son las siguientes,

$a = @(1, 2, 3, 4)
$a = 1, 2, 3, 4
$a = Write-Output 1, 2, 3, 4

Y por supuesto, que también lo puedes hacer como resultado de la ejecución de un cmdlet, como te mencionaba anteriormente,

$ps = Get-Process

Accediendo a los elementos del array

Una vez ya tienes todos los elementos que quieres en tu array, el siguiente paso es revisar cada uno de los elementos del array o incluso modificarlo en el caso de que fuera necesario. Para acceder a cada uno de los elementos del array, lo puedes hacer de la siguiente forma,

PS> $a = 1, 2, 3, 4
PS> $a[0]
1

El primer elemento de un array es el elemento 0.

Llegados a este punto te tengo que dar una buena noticia, y esto es que PowerShell, te ofrece mas opciones que otros lenguajes a la hora de obtener valores de un array. Y es que hasta al momento solo has obtenido un único valor, ¿pero es posible obtener varios valores de una sola llamada?. Si, fíjate en el siguiente ejemplo,

PS> $a = 'uno', 'dos', 'tres', 'cuatro', 'cinco'
PS> Write-Output $a[0, 1, 2]
uno
dos
tres

Pero esta no es ni mucho menos la única opción que tienes, también podrías hacerlo de la siguiente forma,

PS> Write-Output $a[0..2]
uno
dos
tres

Pero no solo puedes obtener los valores en sentido directo, sino que también los puedes obtener en sentido inverso ¿como?

PS> Write-Output $a[2..0]
tres
dos
uno

Y lo mejor todavía, ¿como obtener el último valor de un array?

PS> Write-Output $a[-1]
cinco

Y ¿que pasa si intentamos obtener un valor que no existe? En el caso del ejemplo anterior, ¿que valor obtendríamos de por ejemplo $a[100]? Pues un $null.

Algunas propiedades y métodos de los array

El primero, mas evidente y te diría que mas utilizado es la propiedad Count, que nos permite conocer el número de elementos que tienes en el array. Así para el ejemplo anterior, el resultado sería,

PS> Write-Output $a.Count
5

Además un array, tiene algunos métodos muy interesantes, como son,

  • Clear para eliminar el contenido, como por ejemplo$a.Clear()`
  • Contains para saber si si un elemento pertence al array, $a.Contains('cinco').
  • GetLowerBound permite obtener el índice mas bajo del array, como por ejemplo, $a.GetLowerBound(0), que nos devolverá en este caso 0.
  • GetUpperBound igual que el anterior pero para obtener el índice mayor. En nuestro ejemplo sería $a.GetUpperBound(0) y el resultado sería 4.
  • IndexOf, te permite obtener el índice de un elemento, por ejemplo, $a.IndexOf('cuatro') devolverá 3.

Además de estos que te comento, tiene algunos mas adicionales que puedes consultar en la documentación oficial de PowerShell, pero si quiero comentarte dos que son especialmente interesantes.

ForEach

El primero de los métodos que seguro que le vas a sacar mucho partido a partir de ahora, si es que todavía no lo conocías, es ForEach. Este método, te permite iterar sobre todos los elementos del array. Por ejemplo,

PS> $a.ForEach({Write-Output $PSItem})
uno
dos
tres
cuatro
cinco

Evidentemente para esto no tiene mucho sentido, pero ¿que tal esto?

PS> $a = 0, 1, 2
PS> $a.ForEach({$PSItem * 3})
0
3
6

o incluso,

PS> $b = $a.ForEach({$PSItem * 3})

Como te habrás fijado $PSItem representa cada uno de los elementos del array.

Where

El otro método realmente interesante es Where. Este método te permite filtrar los elementos del array y obtener un nuevo array, con solo aquellos elementos que cumplen la condición que hayas establecido. Por ejemplo,

PS> $a = 0, 1, 2, 3, 4, 5, 6
PS> $a.Where({$PSItem > 4})
5
6

Actualizar elementos del array

Lo último que te quedaría, sería ver como puedes, modificar los elementos del array. Recuerda que el tamaño del array es fijo, con lo que solo puedes modificar su contenido, no la cantidad de elementos. Así, para cambiar un valor concreto del array, lo puedes hacer de la siguiente forma,

$a[1] = 5

Fácil ¿no te parece?.

Operadores

Pero si creías que esto era todo con los array, estás muy equivocado, porque exixten una serie de operadores, que te van a permitir trabajar con arrays, y exprimirlos al máximo.

  • -join, te permite convertir el array en una cadena de texto uniendo todos los elementos del array. Por ejemplo,
PS> $a = 1, 2, 3
PS> $a -join '-'
1-2-3
  • -replace reemplaza todas las ocurrencias de un elemento por otro elemento, como por ejemplo,
PS> $a = 1, 2, 3
PS> $a -replace 1,3
3
2
3
  • -split parte la cadena por el elemento indicado
  • -contains devolverá True si el array contiene el valor indicado
  • -in igual que el anterior, pero al revés. En este caso preguntamos si un determinado elemento está en el array. Por ejemplo 1 -in $a.

Diccionarios en PowerShell

Otro tipo de datos realmente interesante en PowerShell, junto con los array, son los diccionarios o Hash Tables. Un diccionario no es mas que un conjunto de pares clave/valor. A continuación, puedes encontrar algunas ejemplos de definición de diccionarios,

PS> $dict = @{1="uno";2="dos";3="tres"}
PS> $dict = @{uno="uno";2="dos";3="tres"}
PS> $dict = @{"uno-y-pico"="uno";2="dos";3="tres"}

Algunos detalles importantes en estas definiciones,

  • cada uno de las parejas clave valor está separada por punto y coma
  • las claves pueden ser tanto números como cadenas de texto, pero en el caso de que la clave tenga caracteres como espacios, guiones, etc, deberá ir entrecomillado.

Hasta el momento, lo que has podido ver en todos los casos son diccionarios no ordenados, fíjate bien,

PS> $dict = @{1="uno";2="dos";3="tres"}
PS> Write-Output $dict

Name                           Value
----                           -----
3                              tres
2                              dos
1                              uno

Si, los quieres ordenados, entonces tienes que definirlo de la siguiente forma,

PS> $dict = [ordened]@{2="dos";1="uno";3="tres"}
PS> Write-Output $dict

Name                           Value
----                           -----
2                              dos
1                              uno
3                              tres

¿Como añadir elementos a un diccionario?

Para añadir un elemento en un diccionario tienes diferentes opciones, pero si conoces otros lenguajes de programación, no te vas a llevar ninguna sorpresa, porque son totalmente predecibles. Por ejemplo,

PS> $dict = @{1="uno"}
PS> $dict[2]="dos"
PS> $dict.Add(3, "tres")

¿Que puedo hacer on un diccionario?

Las posibilidades que te ofrece un diccionario son muy similares a las que te ofrece un array, al fin y al cabo, son primos hermanos. Pero, además tienes algunas opciones adicionales. Por ejemplo si quieres obtener todas las claves del diccionario, lo puedes hacer de la siguiente forma,

PS> $dict.Keys

De la misma forma, si en lugar de querer obtener las claves, quieres obtener los valores contenidos en el diccionario, lo puedes hacer con,

PS> $dict.Values

Si quieres imprimir el diccionario ordenado por la clave, lo puedes hacer ejecutando la siguiente instrucción,

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

Y si, por el contrario, en lugar de querer imprimirlo ordenado por la clave, lo quieres imprimir ordenador por el valor, lo puedes hacer de la siguiente manera,

PS> $dict.GetEnumerator() | Sort-Object -Property value

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *