Capítulo 7: Variables que guardan múltiples valores
Arrays
Básicamente, un array es una lista de valores, de cualquier tipo, que podemos identificar de forma individual por la posición que ocupan dentro de la lista. Las posiciones de los diferentes elementos se numeran a partir de cero.
Crear un array
A diferencia de lo que se hace en otros lenguajes de programación, en PowerShell no hay que definir una variable de forma diferente para que actúe como un array. Es suficiente con asignarle un grupo de valores, siguiendo este formato:
Por ejemplo, el siguiente código sería correcto:
Este es, digamos, el formato explícito. Sin embargo, también sería correcto usar expresiones como estas:
o, incluso, usando un rango de valores:
Como hemos dicho más arriba, cada elemento de un array puede ser de un tipo diferente aunque, si necesitamos restringir el tipo de dato que podemos almacenar en ella, basta con indicarlo delante del nombre de la variable. En ese caso, como vamos a almacenar valores enteros, seguiremos el siguiente formato:
No obstante, la misma idea es válida para cualquier otro tipo de dato.
Aunque hemos utilizado el formato estándar, la definición explícita de tipo es válida también con la sintaxis reducida que hemos visto antes:
o también:
Incluso podemos crear un array vacío al que ir añadiendo elementos más tarde:
Mostrar el contenido de un array
Si queremos ver en pantalla el contenido de todo el array en un momento dado, podemos utilizar la misma técnica que con una variable simple:
Utilizar un elemento individual del array
Para acceder a un elemento concreto del array, basta con escribir su nombre seguido de la posición que necesitamos, encerrada entre corchetes.
Por ejemplo, para mostrar el primer elemento del array anterior, escribiríamos esto:
Aunque, si lo que queremos es utilizar el elemento dentro de una expresión, nos limitamos a utilizar la notación anterior como si se tratara de una variable simple.
Por ejemplo, para incrementar en uno el valor del elemento, haríamos esto:
o incluso esto:
Arrays como objetos
Ya dijimos en otro apartado que, internamente, PowerShell trata a todas las variables como objetos. Y, aunque aquí no profundicemos en los conceptos relacionados con la programación orientada a objetos, sí debemos saber que, gracias a esta característica, disponemos de herramientas que nos facilitan la creación, manipulación, búsqueda y ordenación de arrays.
Por ejemplo, si quisiéramos saber cuántos elementos tiene un array, bastaría con escribir lo siguiente:
Y, como vemos a continuación, el valor devuelto para el array de ejemplo que hemos venido utilizando, sería 4:
Para conocer en detalle todas las características de la clase Array, puedes recurrir al siguiente enlace: https://msdn.microsoft.com/en-us/library/system.array(v=vs.110).aspx
Recorrer un array
Muchas veces necesitamos realizar operaciones que afecten a todos los elementos de un array. Para estas situaciones podemos utilizar una estructura repetitiva controlada por una variable que actúe como índice del array.
Para entenderlo, quizás lo mejor sea recurrir a un ejemplo; veamos cómo multiplicar por dos cada uno de los valores contenidos en un array:
Observa que la variable $i comienza con el valor cero y, en cada iteración, se incrementa en uno hasta llegar al valor de la última posición del array. Luego, dentro del bloque de código, se utiliza la variable $i para hacer referencia a un elemento particular del array (primero al de la posición 0, luego al de la posición 1, etc.)
Por supuesto, nos vale cualquier estructura repetitiva, siempre que actúe de forma equivalente a ésta.
No obstante, recuerda que existe una de ellas que está específicamente diseñada para actuar sobre colecciones de datos. Me refiero a la estructura foreach.
Una de las ventajas de usar foreach para recorrer un array es que no necesitamos una variable que vaya tomando el valor de cada posición. Por ejemplo, si queremos resolver la tarea anterior, bastaría con el siguiente código:
De cualquier modo, debemos tener en cuenta una sutil diferencia: mientras en el caso de for estamos accediendo a un elemento del array cada vez, en el caso de foreach se hace una copia de dicho elemento en la variable $elem. Esto significa que, al cambiar el valor de la variable $elem, no estamos cambiando el valor original en el array.
Para comprobarlo, podríamos modificar el ejemplo anterior para que nos vaya mostrando el resultado de cada operación y, al final, el contenido del array:
Observa que, por primera vez, hemos utilizado un argumento en el cmdlet Write-Host. Se trata de -NoNewline, que evita que se produzca un cambio de línea después de ejecutarlo. Así, hemos conseguido que todos los números mostrados en el interior de la estructura foreach aparezcan en la misma línea.
También hemos utilizado un carácter especial (`n) en el último Write-Host. En este caso, la intención era, precisamente, producir un cambio de línea.
Otro inconveniente de foreach es que siempre recorre todo el array. Si necesitáramos recorrer sólo algunas de sus posiciones, o no quisiéramos hacerlo en el orden preestablecido, quizás sería más recomendable una estructura diferente.
Por ejemplo, imaginemos que tenemos un array que guarda nombres de productos en las posiciones impares y su precio correspondiente en las posiciones pares. Para aplicar un descuento del 10% a todos los productos, la solución más sencilla pasa por no utilizar foreach. Por ejemplo, podríamos aplicar la siguiente solución:
Como PowerShell no tiene en cuenta los saltos de línea ni el exceso de espacios, hemos hecho nuestro código más legible añadiéndolos según nuestro criterio.
Añadir y quitar valores en un array
Cuando necesitamos que un array crezca con nuevos elementos, basta con utilizar el operador de suma (+).
Por ejemplo, podemos crear un array vacío y añadir elementos a medida que los vaya facilitando un usuario:
También podemos usar el operador de suma para unir dos listas y obtener una tercera:
… Incluso podemos añadir una lista a otra:
En ocasiones, la salida de un cmdlet consiste en un array. Esto significa que podríamos asignarla directamente a una variable de este tipo. Un ejemplo puede ser el cmdlet Get-ChildItem que ya conocemos del capítulo anterior.
Get-ChildItem permite obtener la lista de archivos de una o varias rutas del disco
Para comprobar que su salida consiste en un array, bastaría con escribir lo siguiente:
Como el resultado es satisfactorio, podemos utilizar un array para almacenar la información que nos ofrece escribiendo algo así:
En realidad, Get-ChildItem devuelve un array de objetos donde cada uno representará un archivo del directorio.
A modo de ejemplo, podemos usar la propiedad name de uno de esos objetos, que nos ofrecerá el nombre del archivo correspondiente.
Sabiendo esto, podríamos utilizar una estructura repetitiva que recorra el array y nos muestre los nombres de los archivos contenidos en el directorio. Algo así:
En cuanto a la eliminación de elementos de una array, no hay un procedimiento sencillo. Probablemente la mejor solución consista en crear un array nuevo y asignarle únicamente los valores que nos interese mantener.
Por ejemplo, supongamos que, en el array anterior, únicamente queremos mantener los nombres de los archivos que comiencen con la letra ‘D’. Podríamos hacer algo así:
En realidad, podríamos haber simplificado un poco escribiendo algo así:
Te animo a que lo analices y saques tus conclusiones…
Actividades resueltas: Trata de resolver las siguientes cuestiones, antes de consultar la respuesta:
-
Crea un script que pida la lista de nombres de una clase. La lista acabará cuando, la persona que la escribe, deje un nombre vacío.
Cuando hayamos terminado, el programa mostrará en pantalla los nombres que hayamos introducido, pero en orden inverso.
Nota: Para añadir un nuevo elemento a un array basta con sumárselo. Por ejemplo:
$var = @(1, 2, 3) $var += 4
Al final, el array tiene los valores 1, 2, 3, 4
-
Escribe un script que pida la lista de nombres de una clase. La lista acabará dejando un nombre vacío.
Cuando hayamos terminado, el programa calculará la longitud media de los nombres (el número total de caracteres introducidos, dividido por el número de nombres).
Por último, mostrará todos aquellos nombres que tengan un número de caracteres superior a la media.
Nota: Para saber el número de caracteres de una variable de texto, podemos usar la propiedad Length. Por ejemplo:
$texto = "Hola" Write-Host $texto.Length
Obtendríamos el valor 4.
-
Escribe un script que contenga dos arrays: El primero tendrá los dígitos del sistema de numeración romano y el segundo sus valores. La definición será parecida a esta:
$dígitos = @("I", "V", "X", "L", "C", "D", "M") $valor = @(1, 5, 10, 50, 100, 500, 1000)
El usuario podrá escribir el carácter de cualquier dígito y el script responderá con su valor. También deberá avisar cuando escribamos un dígito que no exista.
-
Partiendo de la idea anterior, escribe un nuevo script que nos pida un valor y nos responda con el dígito correspondiente en el sistema de numeración romano. También avisará cuando no se encuentre el valor aportado.