Anuncios

Bienvenidos sean a este post, hoy hablaremos sobre este tipo de coleccion.

Anuncios

Como dijimos este es otro tipo de coleccion, al igual que Array o Vector pero este nos permite asociar una clave al elemento almacenado en lugar de asignarle una posicion, esto lo hace mediante una funcion de hashing la cual determina como se almacena las claves y datos en la memoria, por lo general la forma de almacenarlo sera:

HashMap<K, V>
Anuncios

Donde K corresponde a la clave que servira de identificacion y V sera el valor que estara relacionado a la clave anterior, para entenderlo mejor vamos a verlo en accion mediante un ejemplo.

Anuncios

Para ello crearemos un nuevo proyecto que llamaremos mapeo, una vez creado modificaremos el codigo generado en main.rs de la siguiente manera:

main.rs

use std::collections::HashMap;

fn main() 
{
	let mut mapa = HashMap::new();

	mapa.insert('A', 10);
	mapa.insert('B', 20);

	let idx = 'A';
	let mapeo = mapa.get(&idx);
	println!("{:?}", mapeo);
}
Anuncios
Anuncios

La primera linea nos permite habilitar a los HashMap para nuestro codigo, luego crearemos el HashMap por medio de new y a este lo llamaremos mapa, despues por medio de insert ingresaremos dos valores, en este caso las claves seran los caracteres y los valores enteros seran los asignados a las claves, luego definiremos una variable que llamaremos idx y le pasaremos el caracter del primer mapeo, luego definiremos otra nueva variable llamada mapeo y en ella almacenaremos el valor obtenido por medio de get y le pasamos la clave por medio de la variable anterior, observen un detalle en este caso le pasamos el operador de referencia porque este metodo lo requiere de esta forma, por esto debimos usar una variable para recuperar la clave, por ultimo mostramos en pantalla el valor obtenido, compilemos y veamos su salida:

tinchicus@dbn001vrt:~/lenguajes/rust/mapeo$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/mapeo`
Some(10)
tinchicus@dbn001vrt:~/lenguajes/rust/mapeo$
Anuncios

Aqui vimos como se crea, como se le puede ingresar informacion y como se puede recuperar pero vamos a darle el verdadero uso, para ello modificaremos el codigo anterior de la siguiente manera:

main.rs

use std::collections::HashMap;

fn main() 
{
	let mut mapa = HashMap::new();

	mapa.insert(String::from("primero"), 10);
	mapa.insert(String::from("segundo"), 20);

	let idx = String::from("primero");
	let mapeo = mapa.get(&idx);
	println!("{:?}", mapeo);
}
Anuncios

Basicamente es similar al codigo anterior pero esta vez usamos claves de tipo String, tanto al usar el insert como la variable que despues usaremos para el get pero porque debemos hacerlo asi? Esto es basicamente debido a que no se implementa Copy trait para este tipo de datos, este trait solo es implementado para tipos primitivos como el codigo anterior, por lo tanto debemos castear correctamente que es de tipo String, el resto del codigo es exactamente lo mismo por lo tanto si lo compilamos obtendremos la misma salida, tomemos este mismo codigo y vamos a modificarlo de la siguiente manera:

Anuncios
Nota:
No se preocupen hablaremos de Copy trait mas adelante en otro post.
Anuncios

main.rs

use std::collections::HashMap;

fn main() 
{
	let mut mapa = HashMap::new();

	mapa.insert(String::from("primero"), 10);
	mapa.insert(String::from("segundo"), 20);

	for (clave, valor) in &mapa
	{
		println!("{}: {}", clave, valor);
	}
}
Anuncios

En este caso eliminamos el uso del get y pasamos a usar un bucle for donde almacenaremos la clave y el valor de mapa en las variables con los mismos nombres respectivamente, para finalmente mostrarlos en pantalla, compilemos y veamos su salida:

tinchicus@dbn001vrt:~/lenguajes/rust/mapeo$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/mapeo`
primero: 10
segundo: 20
tinchicus@dbn001vrt:~/lenguajes/rust/mapeo$
Anuncios
Nota:
Del bucle for hablaremos un poco mas adelante en otro post.
Anuncios

Como pueden ver nos devolvio todos los valores dentro del mapa, donde cada clave corresponde a un valor, pero podemos hacer mas cosas, por ejemplo podemos actualizar un valor en una clave para ello tomaremos el codigo anterior y lo modificaremos de la siguiente manera:

main.rs

use std::collections::HashMap;

fn main() 
{
	let mut mapa = HashMap::new();

	mapa.insert(String::from("primero"), 10);
	mapa.insert(String::from("segundo"), 20);

	mapa.insert(String::from("primero"), 30);

	for (clave, valor) in &mapa
	{
		println!("{}: {}", clave, valor);
	}
}
Anuncios

Como pueden ver fue simplemente agregando una nueva linea donde usamos nuevamente a insert y con simplemente repetir la clave que debemos actualizar esto se hara automaticamente pero tambien podemos necesitar que se actualice el valor unicamente si esta vacio, para ello tomaremos el codigo anterior y lo modificaremos de la siguiente manera:

main.rs

use std::collections::HashMap;

fn main() 
{
	let mut mapa = HashMap::new();

	mapa.insert(String::from("primero"), 10);
	mapa.insert(String::from("segundo"), 20);

	mapa.entry(String::from("primero")).or_insert(30);
	mapa.entry(String::from("tercero")).or_insert(40);

	for (clave, valor) in &mapa
	{
		println!("{}: {}", clave, valor);
	}
}
Anuncios

En este caso no usamos a insert sino que usamos a entry donde le pasaremos una clave y luego el metodo or_insert donde le pasamos un valor, en este caso observen que primero usamos una de las claves anteriores y luego una nueva, este metodo verifica si existe una clave con el nombre indicado en caso de ser asi procede a omitir el ingreso de datos de lo contrario lo hace, compilemos y veamos su salida:

tinchicus@dbn001vrt:~/lenguajes/rust/mapeo$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/mapeo`
primero: 10
segundo: 20
tercero: 40
tinchicus@dbn001vrt:~/lenguajes/rust/mapeo$
Anuncios

Como pueden ver se cumplio lo comentado anteriormente donde al encontrar una clave con ese nombre no lo actualizo y en el caso de la nueva si lo hizo, vamos a ver la ultima posibilidad y para ello modificaremos el codigo de la siguiente manera:

main.rs

use std::collections::HashMap;

fn main() 
{
	let texto = "hola mundo maravilloso mundo";

	let mut mapa = HashMap::new();

	for palabra in texto.split_whitespace()
	{
		let contar = mapa.entry(palabra).or_insert(0);
		*contar += 1;
	}

	for (clave, valor) in &mapa
	{
		println!("{}: {}", clave, valor);
	}
}
Anuncios
Anuncios

Este codigo cambio sustancialmente debido a que debemos mostrar una propiedad unica de este tipo de dato, primero definiremos una variable de tipo String con un texto, lo siguiente sera crear el hash map, despues tenemos un bucle for donde almacenaremos cada palabra en una variable llamada de la misma forma, esto lo logramos gracias al metodo split_whitespace que convierte al texto en una coleccion dividido por los espacios en blanco, dentro de nuestro bucle tenemos una variable llamada contar donde agregaremos una nueva entrada por medio de entry y usaremos a or_insert donde le pasaremos el valor de 0 para el caso de que no exista, luego incrementaremos a contar en 1 pero observen que usamos a un apuntador, esto es para desreferenciar a la variable e ir mas alla del rango o scope, esto a su vez almacenara en cada entrada el valor de contar, por ultimo por medio de otro bucle mostraremos todas las claves y valores como hicimos en ejemplos anteriores, compilemos y veamos su salida:

tinchicus@dbn001vrt:~/lenguajes/rust/mapeo$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/mapeo`
mundo: 2
hola: 1
maravilloso: 1
tinchicus@dbn001vrt:~/lenguajes/rust/mapeo$
Anuncios

Observen como se nos dividio en tres claves con los valores de contar para cada una de ellas pero porque tres y no cuatro? Porque una esta repetida, mundo, y por lo tanto la vuelve a utilizar y por esta razon tambien el valor dando como resultado el 2, y esta es otra de las caracteristicas de esta tipo de dato, no se puede tener claves duplicadas dentro de un Hash Map.

Anuncios

En resumen, hoy hemos visto Hash Map, que es, como trabaja, como se diferencia con respecto a otras colecciones, hemos visto como crearla, como agregar datos, como recuperarlos y otras posibilidades que tenemos disponibles para manipular la informacion en ella, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50