Perl2 arrays

Preview:

DESCRIPTION

Diapositivas utilizadas en el curso de introducción a perl.

Citation preview

Programación en Perl Arrays

Arrays

Los escalares sirven para almacenar “una cosa de algo”

Los arrays son una forma de almacenar “muchas cosas de algo”

Definiciones:

Lista: colección ordenada de escalares

Array: variable que contiene una lista

Arrays

Los arrays/listas están ordenados, es decir, tienen una determinada secuencia.

Los array/listas están indexados por enterors empezando en cero

Dado que los arrays son listas de escalares, pueden almacenar indistintamente cadenas o números.

Pueden tener cualquier número de elementos. El límite lo pone la memoria disponible.

Arrays: accediendo a sus elementos

1.$marcas[0] = "Ford";2.$marcas[1] = "Mercedes";3.$marcas[2] = "Kia";

El “nombre” de este array es marcas.

Podemos tener en el mismo script un escalar $marcas y un array marcas.

El índice es un número, por lo que podemos acceder usando $marcas[$indice - 4]

¿Qué mostrará por pantalla say $marcas[‘3rosas’ - 2];?

Arrays: accediendo a sus elementos

1.$marcas[0] = "Ford";2.$marcas[1] = "Mercedes";3.$marcas[2] = "Kia";

El “nombre” de este array es marcas.

Podemos tener en el mismo script un escalar $marcas y un array marcas.

El índice es un número, por lo que podemos acceder usando $marcas[$indice - 4]

¿Qué mostrará por pantalla say $marcas[‘3rosas’ - 2];?

Mercedes

Arrays

¿qué pasa si nos salimos de los límites del array?

1.$marcas[0] = "Ford";2.$marcas[1] = "Mercedes";3.$marcas[2] = "Kia";4.$marcas[100] = "Toyota";

Arrays

¿qué pasa si nos salimos de los límites del array?

1.$marcas[0] = "Ford";2.$marcas[1] = "Mercedes";3.$marcas[2] = "Kia";4.$marcas[100] = "Toyota";

Se crean 98 elementos y se les asigna el valor undef

Arrays: último índice

Arrays: último índice1.$indice = $#marcas; #índice del último elemento, 100

2.$elementos = $indice + 1; #hay 101 elementos

3.$marcas[$#marcas] = “Honda” # Sobreescribimos el último                            # elemento

Arrays: último índice1.$indice = $#marcas; #índice del último elemento, 100

2.$elementos = $indice + 1; #hay 101 elementos

3.$marcas[$#marcas] = “Honda” # Sobreescribimos el último                            # elemento

Como acceder al último elemento es algo que ocurre muy a menudo, perl nos da un “atajo” usar

íncides negativos1.$marcas[-1] #Devuelve Honda

2.$marcas[-101] #Devuelve el primer elemento

3.$marcas[-200] = “Honda” # Error

Arrays: literales de lista(1, 3, 5, 7)

(“nombre”, 3, 5.5, “López”)

() #Lista vacía

(1..100) # lista de 100 enteros usando el operador de rango

(5..1) #lista vacía (no funciona hacia abajo)

($n..$m)

(0..$#marcas)

($n+10..$p+$q)

(‘maría’, ‘mariano’, ‘luis’, ‘rodrigo’, ‘ana’)

Arrays: qw

En lugar de

(‘maría’, ‘mariano’, ‘luis’, ‘rodrigo’, ‘ana’)

podemos hacer lo siguiente

qw( maría mariano luis rodrigo ana )

Cada “palabra” se trata como una cadena entre comilla simple, así que no podemos usar secuencias de escape o interpolación de variables

Arrays: qw

Otra forma de poner la lista es

qw( maría mariano luis rodrigo ana)

Arrays: qw

Podemos usar cualquier delimitadorqw! maría mariano luis rodrigo ana !qw# maría mariano luis rodrigo ana #

Podemos usar también los siguientes “pares” de delimitadoresqw{ maría mariano luis rodrigo ana }qw[ maría mariano luis rodrigo ana ]qw< maría mariano luis rodrigo ana >

Si necesitamos incluir el delimitador tenemos que escaparlo:qw! google msn yahoo\! apple !

Arrays: asignación de listas

Asignar los valores de una lista a un conjunto de variables:

($nombre, $apellido1, $apellido2) = (‘Luis’, ‘López’, ‘Pérez’);

Podemos intercambiar valores

($admin, $superadmin) = ($superadmin, $admin)

Arrays: asignación de listas

¿Qué pasa si el número de elementos no coincide?

($nombre, $apellido1) = qw( luis López Pérez)

El “Pérez” de la derecha se descarta.

($nombre, $apellido1, $apellido2) = qw( luis López )

$apellido2 vale undef.

Arrays: asignación de listas

Arrays: asignación de listas

¿y si queremos asignar la lista a un array?

($users[0], $users[1], $users[2]) = qw/ pilar pepe pedro /

Arrays: asignación de listas

¿y si queremos asignar la lista a un array?

($users[0], $users[1], $users[2]) = qw/ pilar pepe pedro /

En lugar de esto podemos utilizar lo siguiente

@users = qw/ pilar pepe pedro /

Arrays: asignación de listas

Más asignaciones de lista a array

@usuarios = qw/ user1 user2 user3 /

@enteros = (1..100)

@todos = (@usuarios, @administradores)

@cosas = (@ususarios, ‘cadena’, entero, $variable)

Arrays: asignación de listas

Muy importante:

@todos = (@usuarios, @administradores)

no es un array de arrays, es la “concatenación” de dos arrays.@todos contiene los elementos de @usuarios seguidos de los elementos de @administradores

Copia de arrays:

@copia = @todos

En realidad esto es una asignación de listas (@todos se expande a lista y se asigna a @copia)

Arrays: funciones y operadores

pop: quita un elemento del array por el final

push: añade un elemento al array por el final

unshift: saca un elemento del array por el principio

shift: añade un elemento al array por el principio

Arrays: funciones y operadores

splice: sirve para obtener “rebanar” de un array

Arrays: funciones y operadores

Arrays: funciones y operadores

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.@borrado = splice @array, 2; # se borra todo después de

Arrays: funciones y operadores

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.@borrado = splice @array, 2; # se borra todo después de

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.@borrado = splice @array, 1, 2; # se borran los elementos

Arrays: funciones y operadores

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.@borrado = splice @array, 2; # se borra todo después de

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.@borrado = splice @array, 1, 2; # se borran los elementos

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.@borrado = splice @array, 1, 2, qw(NUEVO); # se borran los # elementos pedro y betty y en su lugar se # añade NUEVO

Arrays: interpolación en cadenas

Arrays: interpolación en cadenas

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.say “Los picapiedra son @picapiedra”;

-----

Los picapiedra son: pablo pedro betty wilma dino

Arrays: interpolación en cadenas

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.say “Los picapiedra son @picapiedra”;

-----

Los picapiedra son: pablo pedro betty wilma dino

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.say “mi email es pedro@picapiedra.com”;

-----

mi email es pedropablo pedro betty wilma dino.com

Arrays: interpolación en cadenas

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.say “mi email es pedro\@picapiedra.com”;

-----

mi email es pedropablo pedro betty wilma dino.com

Arrays: interpolación en cadenas

1.@datos = qw( pablo pedro betty wilma dino );

2.$datos = “ESCALAR”

3.print "$datos[3]\n"; # imprime $datos[3] -> wilma

4.print "${datos}[3]\n"; # imprime "ESCALAR[3]"                       #(protegido por los corchetes)

5.print "$datos"."[3]\n"; # imprime ESCALAR[3]

6.print "$datos\[3]\n"; # imprime ESCALAR[3], el corchete está                     # escapado

Arrays: foreach

Estructura de control que itera sobre todos los elementos del array

En cada iteración, la variable $dato almacena uno de los elementos del array.

1.@datos = qw( pablo pedro betty wilma dino );

2.foreach $dato (@datos) {

3. print "El personaje es $dato.\n";

4.}

Arrays: foreach

La variable $dato NO es una copia del elemento del array, por lo que si se modifica en el bucle, se modifica el array.

El valor de la variable de control después del bucle recupera el valor que tenía antes.

Arrays: foreach

La variable $dato NO es una copia del elemento del array, por lo que si se modifica en el bucle, se modifica el array.

El valor de la variable de control después del bucle recupera el valor que tenía antes.

...pero esto son muchos caracteres que escribir ¿no era perl un lenguaje conciso?

Arrays: foreach

1.#Vamos a hacerlo más corto. No necesitamos el array datos

2.foreach $dato ( qw( pablo pedro betty wilma dino ) ) {3. print "El personaje es $dato.\n";4.}5. 6.#No necesitamos la variable $dato, podemos usar $_7.foreach ( qw( pablo pedro betty wilma dino ) ) {8. print "El personaje es $_.\n";9.}10. 11.#Dado que sólo tenemos una instrucción dentro del bucle podemos hacer lo siguiente

12.print "El personaje es $_.\n" foreach ( qw( pablo pedro betty wilma dino ) );

Arrays: sort y reverse

sort: Devuelve un array con los elementos ordenador por orden alfabético

@ordenado = sort (@array)

@numeros = sort 97..110

reverse: Devuelve un array con los elementos en orden inverso

@reves = reverse @array

Arrays: each

A partir de la versión 5.12 de perl, es posible usar la función each con arrays (antes sólo se podía con hashes)

1.use 5.012;2.#Recorriendo un array con each3.my @datos = qw( pablo pedro betty wilma dino );4.while(my($indice,$valor) = each @datos) {5.        say "$indice: $valor";6.}7.#Si no podemos usar each, tenemos que hacerlo con foreach8.@datos = qw( pablo pedro betty wilma dino );9.foreach my $indice (0..$#datos) {10.        say "$indice: $datos[$indice]";11.}

Arrays: for

1.@datos = qw( pablo pedro betty wilma dino );

2.for($i = 0; $i < $#datos; $i++ ) {

3.        say "$i: $datos[$i]";

4.}

LO MÁS IMPORTANTE DEL CURSO:

LO MÁS IMPORTANTE DEL CURSO:

LOS CONTEXTOS DE EJECUCIÓN

Contextos

Que sea importante no quiere decir que sea difícil. Veamoslo

Contextos

Que sea importante no quiere decir que sea difícil. Veamoslo

Dada una expresión, esta puede significar cosas diferentes en función de cómo y dónde se usa

Contextos

Que sea importante no quiere decir que sea difícil. Veamoslo

Dada una expresión, esta puede significar cosas diferentes en función de cómo y dónde se usa

Esto no es para vosotros un concepto nuevo ni mucho menos. Por ejemplo:

Contextos

Que sea importante no quiere decir que sea difícil. Veamoslo

Dada una expresión, esta puede significar cosas diferentes en función de cómo y dónde se usa

Esto no es para vosotros un concepto nuevo ni mucho menos. Por ejemplo:

Me LARGO de aquí

Contextos

Que sea importante no quiere decir que sea difícil. Veamoslo

Dada una expresión, esta puede significar cosas diferentes en función de cómo y dónde se usa

Esto no es para vosotros un concepto nuevo ni mucho menos. Por ejemplo:

Me LARGO de aquí

Que día tan LARGO

Contextos

Que sea importante no quiere decir que sea difícil. Veamoslo

Dada una expresión, esta puede significar cosas diferentes en función de cómo y dónde se usa

Esto no es para vosotros un concepto nuevo ni mucho menos. Por ejemplo:

Me LARGO de aquí

Que día tan LARGO

Si te pregunto por el significado de la palabra LARGO tu respuesta dependerá del contexto.

Contextos

Contextos

Ya hemos visto un ejemplo de contextos:

2 * 3 = 6

2 x 3 = 222

El operador define el contexto de la expresión y, en función de este, se trata 2 y 3 como cadenas o como números.

Contextos

Cuando perl analiza una expresión siempre espera un escalar o una lista.

Una expresión siempre devuelve el valor apropiado según el contexto en el que se evalúe

Veamos qué significa esto con un ejemplo:

¿Qué significa la expresión @datos?

En un contexto de lista es la lista de elementos del array

En un contexto escalar significa el número de elementos del array

Contextos

1.@datos = qw( pablo pedro betty wilma dino );2.$ordenados = sort @datos # contexto lista: sort espera # una lista

3.$valor = 45 + @datos # contexto escalar: el operador + # opera sobre escalares. # $valor valdrá 50

4.$valor = @datos # contexto escalar: asignación a un escalar. # $valor valdrá 5

¿Qué ocurre si intentamos utilizar una expresión que genera una lista en un contexto escalar?

Por ejemplo: reverse @array

Es una expresión que genera una lista con los elementos del array en orden inverso@resultado = reverse qw( elem1 elem2 elem3 )

¿y si hacemos lo siguiente?$resultado = reverse qw( elem1 elem2 elem3 )

¿Qué vale resultado?

Contextos

¿Qué ocurre si intentamos utilizar una expresión que genera una lista en un contexto escalar?

Por ejemplo: reverse @array

Es una expresión que genera una lista con los elementos del array en orden inverso@resultado = reverse qw( elem1 elem2 elem3 )

¿y si hacemos lo siguiente?$resultado = reverse qw( elem1 elem2 elem3 )

¿Qué vale resultado? 3mele2mele1mele

Contextos

Contextos

¿Y porqué devuelve eso y no otra cosa?

Devuelve eso porque el sentido común de Larry Wall determinó en su día que eso era así.

Hasta que aprendamos a tener el sentido común de Larry, tendremos que mirar la documentación:

perldoc -f reverseperldoc -f sort

Contextos

¿Qué ocurre si intentamos utilizar una expresión que genera un escalar en un contexto de lista?

Se genera una lista de un único elemento:

1.@array = 6 * 7; # Se crea un array de un elemento (42)

2.@array = "hola" . ' a ' . "todos";

Contextos

Cuidado con la siguiente expresión:

1.@array = undef; # Se genera un array de un elemento undef # (undef)

2.say "elementos: $#array";

3. @array = (); #Esto es un array de cero elementos

4.say "elementos: $#array";

Contextos

A veces podemos necesitar forzar un contexto escalar donde perl espera una lista

1.@picapiedra = qw( pablo pedro betty wilma dino );

2.print "¿cuántos son los picapiedra?\n";

3.say "Los picapiedra son ", @picapiedra ; # MAL, imprime los nombres

4.say "los picapiedra son ", scalar @picapiedra; # Correcto, da el número de elementos del array

Contextos: <STDIN>

En contexto de lista, este operador devuelve todas las líneas de entrada en un array

1.@lines = <STDIN>; # Lee todas las líneas de la entrada # estándar

Contextos: <STDIN>

Si la entrada viene de un fichero, se lee todo el fichero en memoria.

Cuando se lee el fichero, se leen también los caracteres de fin de línea. Podemos utilizar chomp en contexto de lista para quitarlos

1.@lines = <STDIN>;2.chomp (@lines);

Contextos: <STDIN>

Si la entrada viene de un fichero, se lee todo el fichero en memoria.

Cuando se lee el fichero, se leen también los caracteres de fin de línea. Podemos utilizar chomp en contexto de lista para quitarlos

1.chomp(@lines = <STDIN>);

Ejercicios1. Escribe un programa que pida al usuario una lista de cadenas en líneas separadas y las

imprima en orden inverso a como se han leído.

2. Escribe un programa que lea una lista de números (cada uno en una línea) hasta un EOF e imprima el nombre de la persona asociada a cada número de la siguiente lista:

mariana, luis, miguel, ramón, rosalía, juan, pablo, natalia

3. Implementar una pila (first in, first out) en perl. Dar al usuario las siguientes opciones:

1. Añadir elemento a la pila

2. Sacar elemento de la pila

3. Imprimir pila

4. Salir