Hashes
## Objetivos de Aprendizaje
- Crear y manipular hashes
- Usar funciones de hash (keys, values, each)
- Verificar existencia y eliminar entradas
- Trabajar con rebanadas de hash
- Comprender el interno de los hashes
## Basicos de Hashes
### Creando Hashes
```perl
use strict;
use warnings;
my %vacio;
my %persona = (
nombre => "Alice",
edad => 30,
ciudad => "Boston",
);
# => es coma gordo, comillas opcionales para identificadores validos
```
### Accediendo a Elementos
```perl
my %persona = (
nombre => "Alice",
edad => 30,
ciudad => "Boston",
);
print $persona{nombre}; # "Alice"
print $persona{edad}; # 30
# Modificar
$persona{edad} = 31;
$persona{email} = "alice@example.com";
```
### Hash desde Arreglos
```perl
my @claves = ("nombre", "edad", "ciudad");
my @valores = ("Alice", 30, "Boston");
my %persona = @claves; # Incorrecto! Crea (nombre, edad, ciudad, @valores)
my %persona = (@claves, @valores); # Correcto
```
### Hash desde Lista
```perl
my %persona = (
nombre => "Alice",
edad => 30,
ciudad => "Boston",
);
# O usando lista directamente
my %datos = ("clave1", "valor1", "clave2", "valor2");
```
## Funciones de Hash
### keys
```perl
my %persona = (
nombre => "Alice",
edad => 30,
ciudad => "Boston",
);
my @k = keys %persona; # ("nombre", "edad", "ciudad")
# Iterar sobre claves
foreach my $clave (keys %persona) {
print "$clave: $persona{$clave}\n";
}
```
### values
```perl
my %persona = (
nombre => "Alice",
edad => 30,
ciudad => "Boston",
);
my @v = values %persona; # ("Alice", 30, "Boston")
```
### each
```perl
my %persona = (
nombre => "Alice",
edad => 30,
ciudad => "Boston",
);
while (my ($clave, $valor) = each %persona) {
print "$clave => $valor\n";
}
```
### Orden de Iteracion
```perl
use strict;
use warnings;
my %nums = (uno => 1, dos => 2, tres => 3);
# Orden no garantizado (pero consistente dentro del programa)
foreach my $clave (keys %nums) {
print "$clave => $nums{$clave}\n";
}
```
## Existencia y Eliminacion
### exists
```perl
my %persona = (
nombre => "Alice",
edad => 30,
);
if (exists $persona{nombre}) {
print "El nombre existe\n";
}
if (!exists $persona{email}) {
print "Sin email\n";
}
```
### delete
```perl
my %persona = (
nombre => "Alice",
edad => 30,
ciudad => "Boston",
);
delete $persona{edad}; # Remover edad
print $persona{edad}; # undef
# Eliminacion segura
delete $persona{$_} for qw(nombre edad ciudad);
```
### Verificacion defined
```perl
my %persona = (
nombre => "Alice",
edad => 30,
email => undef,
);
print defined $persona{nombre}; # verdadero
print defined $persona{email}; # falso (aunque la clave existe)
print defined $persona{nonexistente}; # falso
```
## Tamano del Hash
```perl
my %persona = (
nombre => "Alice",
edad => 30,
ciudad => "Boston",
);
my $count = scalar keys %persona; # 3
print "El hash tiene $count entradas\n";
# Verificacion vacio
if (keys %persona == 0) {
print "El hash esta vacio\n";
}
```
## Ordenamiento de Hashes
### Ordenar por Claves
```perl
my %puntuaciones = (
bob => 87,
alice => 95,
carol => 92,
);
foreach my $nombre (sort keys %puntuaciones) {
print "$nombre: $puntuaciones{$nombre}\n";
}
```
### Ordenar por Valores
```perl
foreach my $nombre (sort { $puntuaciones{$a} <=> $puntuaciones{$b} } keys %puntuaciones) {
print "$nombre: $puntuaciones{$nombre}\n";
}
# Orden inverso
foreach my $nombre (sort { $puntuaciones{$b} <=> $puntuaciones{$a} } keys %puntuaciones) {
print "$nombre: $puntuaciones{$nombre}\n";
}
```
## Rebanadas de Hash
### Rebanada Basica
```perl
my %persona = (
primero => "Alice",
ultimo => "Smith",
edad => 30,
);
# Acceso multiple
my ($primero, $ultimo) = @persona{qw(primero ultimo)};
# Asignacion multiple
@persona{qw(primero, ultimo)} = ("Bob", "Jones");
```
### Rebanada para Inicializacion
```perl
my @campos = qw(nombre edad ciudad);
my @vals = ("Alice", 30, "Boston");
my %persona;
@persona{@campos} = @vals;
```
## Referencias de Hash
### Creando Referencias
```perl
my %persona = (
nombre => "Alice",
edad => 30,
);
my $ref = \%persona;
# Acceder via referencia
print $ref->{nombre}; # "Alice"
```
### Hash Anonymous
```perl
my $persona = {
nombre => "Alice",
edad => 30,
};
print $persona->{nombre}; # "Alice"
```
### Desreferenciando
```perl
my $ref = { a => 1, b => 2 };
my %hash = %$ref;
# O con llaves si es ambiguo
my %hash = %{ $ref };
```
## Hashes Anidados
```perl
use strict;
use warnings;
my %empresa = (
ingenieria => {
alice => { nombre => "Alice", titulo => "Ingeniera" },
bob => { nombre => "Bob", titulo => "Gerente" },
},
ventas => {
carol => { nombre => "Carol", titulo => "Representante de Ventas" },
},
);
print $empresa{ingenieria}{alice}{titulo}; # "Ingeniera"
# Estilo de referencia
my $ing = $empresa{ingenieria};
print $ing->{alice}{nombre}; # "Alice"
```
## Valores por Defecto
### Autovivificacion
```perl
my %conteos;
$conteos{manzana}++; # Crea manzana => 1 (no error undef)
$conteos{banana} += 5; # Crea banana => 5
# Sin autovivificacion
my %seguro;
if (exists $seguro{clave}) {
$seguro{clave}++;
} else {
$seguro{clave} = 1;
}
```
### Operador defined-or
```perl
my %hash = (conteo => 0);
$hash{conteo} //= 10; # No cambiara (0 esta definido)
$hash{nuevo} //= 10; # Establece nuevo => 10
# vs || que usa veracidad
$hash{conteo} ||= 10; # Cambiaria 0 a 10!
```
## Hash como Conjunto
```perl
# Usando hash para valores unicos
my %visto;
my @unico;
foreach my $item (@items) {
if (!$visto{$item}++) {
push @unico, $item;
}
}
# Operaciones simples de conjuntos
my %set1 = map { $_ => 1 } qw(a b c);
my %set2 = map { $_ => 1 } qw(b c d);
# Union
my %union = (%set1, %set2);
# Interseccion
my @interseccion = grep { $set1{$_} && $set2{$_} } (keys %set1, keys %set2);
```
## Trucos Utiles de Hash
### Invertir Hash
```perl
my %original = (a => 1, b => 2, c => 3);
my %invertido = reverse %original;
print "$invertido{1}\n"; # "a"
```
### Contar Ocurrencias
```perl
my @palabras = qw(manzana banana manzana cereza banana manzana);
my %conteo;
foreach my $palabra (@palabras) {
$conteo{$palabra}++;
}
print $conteo{manzana}; # 3
```
### Invertir un Hash
```perl
my %positivo = (a => 1, b => 2, c => 3);
my %negativo = reverse %positivo;
print "$negativo{1}\n"; # "a"
```
## Resumen
- Los hashes se crean con el sigil `%` y pares clave-valor
- Usa `=>` (coma gordo) para legibilidad
- `keys`, `values`, `each` para iteracion
- `exists` verifica existencia de clave
- `delete` elimina entrada
- Las rebanadas de hash acceden a multiples valores
- Las referencias usan `->` para acceso
- Los hashes no preservan orden (pre 5.38)
- Utiles para contar, valores unicos, tablas de busqueda
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →