Rust - Colecciones

La biblioteca de colección estándar de Rust proporciona implementaciones eficientes de las estructuras de datos de programación de propósito general más comunes. Este capítulo analiza la implementación de las colecciones de uso común: Vector, HashMap y HashSet.

Vector

Un vector es una matriz de tamaño variable. Almacena valores en bloques de memoria contiguos. La estructura predefinida Vec se puede utilizar para crear vectores. Algunas características importantes de un vector son:

  • Un vector puede crecer o reducirse en tiempo de ejecución.

  • Un Vector es una colección homogénea.

  • Un vector almacena datos como una secuencia de elementos en un orden particular. A cada elemento de un vector se le asigna un número de índice único. El índice comienza en 0 y sube hasta n-1, donde n es el tamaño de la colección. Por ejemplo, en una colección de 5 elementos, el primer elemento estará en el índice 0 y el último elemento estará en el índice 4.

  • Un vector solo agregará valores hasta (o cerca) del final. En otras palabras, un vector se puede utilizar para implementar una pila.

  • La memoria para un vector se asigna en el montón.

Sintaxis: creación de un vector

let mut instance_name = Vec::new();

El método estático new () de la estructura Vec se utiliza para crear una instancia de vector.

Alternativamente, también se puede crear un vector usando el vec! macro. La sintaxis es la siguiente:

let vector_name = vec![val1,val2,val3]

La siguiente tabla enumera algunas funciones de la estructura Vec más utilizadas.

No Señor Método Firma y descripción
1 nuevo()

pub fn new()->Vect

Construye un nuevo Vec vacío. El vector no se asignará hasta que se inserten elementos en él.

2 empujar()

pub fn push(&mut self, value: T)

Agrega un elemento al final de una colección.

3 eliminar()

pub fn remove(&mut self, index: usize) -> T

Elimina y devuelve el elemento en el índice de posición dentro del vector, desplazando todos los elementos después a la izquierda.

4 contiene ()

pub fn contains(&self, x: &T) -> bool

Devuelve verdadero si el segmento contiene un elemento con el valor dado.

5 len ()

pub fn len(&self) -> usize

Devuelve el número de elementos del vector, también conocido como 'longitud'.

Ilustración: Creación de un vector - nuevo ()

Para crear un vector, usamos el método estático new -

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);
   v.push(40);

   println!("size of vector is :{}",v.len());
   println!("{:?}",v);
}

El ejemplo anterior crea un vector usando el método estático new () que se define en la estructura Vec . La función push (val) agrega el valor pasado como parámetro a la colección. La función len () devuelve la longitud del vector.

Salida

size of vector is :3
[20, 30, 40]

Ilustración: Creación de un vector - vec! Macro

El siguiente código crea un vector usando el vec! macro. El tipo de datos del vector se infiere el primer valor que se le asigna.

fn main() {
   let v = vec![1,2,3];
   println!("{:?}",v);
}

Salida

[1, 2, 3]

Como se mencionó anteriormente, un vector solo puede contener valores del mismo tipo de datos. El siguiente fragmento arrojará un error [E0308]: error de tipos no coincidentes .

fn main() {
   let v = vec![1,2,3,"hello"];
   println!("{:?}",v);
}

Ilustración: empujar ()

Agrega un elemento al final de una colección.

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);
   v.push(40);
   
   println!("{:?}",v);
}

Salida

[20, 30, 40]

Ilustración: eliminar ()

Elimina y devuelve el elemento en el índice de posición dentro del vector, desplazando todos los elementos después a la izquierda.

fn main() {
   let mut v = vec![10,20,30];
   v.remove(1);
   println!("{:?}",v);
}

Salida

[10, 30]

Ilustración - contiene ()

Devuelve verdadero si el segmento contiene un elemento con el valor dado:

fn main() {
   let v = vec![10,20,30];
   if v.contains(&10) {
      println!("found 10");
   }
   println!("{:?}",v);
}

Salida

found 10
[10, 20, 30]

Ilustración: len ()

Devuelve el número de elementos del vector, también conocido como 'longitud'.

fn main() {
   let v = vec![1,2,3];
   println!("size of vector is :{}",v.len());
}

Salida

size of vector is :3

Acceder a valores desde un vector

Se puede acceder a los elementos individuales de un vector utilizando sus números de índice correspondientes. El siguiente ejemplo crea un anuncio vectorial que imprime el valor del primer elemento.

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);

   println!("{:?}",v[0]);
}
Output: `20`

Los valores de un vector también se pueden recuperar utilizando una referencia a la colección.

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);
   v.push(40);
   v.push(500);

   for i in &v {
      println!("{}",i);
   }
   println!("{:?}",v);
}

Salida

20
30
40
500
[20, 30, 40, 500]

HashMap

Un mapa es una colección de pares clave-valor (llamados entradas). No hay dos entradas en un mapa que puedan tener la misma clave. En resumen, un mapa es una tabla de búsqueda. Un HashMap almacena las claves y los valores en una tabla hash. Las entradas se almacenan en un orden arbitrario. La clave se utiliza para buscar valores en el HashMap. La estructura HashMap se define en elstd::collectionsmódulo. Este módulo debe importarse explícitamente para acceder a la estructura HashMap.

Sintaxis: Creación de un HashMap

let mut instance_name = HashMap::new();

El método estático new () de la estructura HashMap se utiliza para crear un objeto HashMap. Este método crea un HashMap vacío.

Las funciones de uso común de HashMap se analizan a continuación:

No Señor Método Firma y descripción
1 insertar()

pub fn insert(&mut self, k: K, v: V) -> Option

Inserta un par clave / valor, si no hay clave, se devuelve None. Después de la actualización, se devuelve el valor anterior.

2 len ()

pub fn len(&self) -> usize

Devuelve el número de elementos del mapa.

3 obtener()

pub fn get<Q: ?Sized>(&lself, k: &Q) -> Option<&V> where K:Borrow Q:Hash+ Eq

Devuelve una referencia al valor correspondiente a la clave.

4 iter ()

pub fn iter(&self) -> Iter<K, V>

Un iterador que visita todos los pares clave-valor en orden arbitrario. El tipo de elemento del iterador es (& 'a K, &' a V).

5 contiene_clave

pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool

Devuelve verdadero si el mapa contiene un valor para la clave especificada.

6 eliminar()

pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>

Elimina una clave del mapa, devolviendo la clave almacenada y el valor si la clave estaba previamente en el mapa.

Ilustración: insertar ()

Inserta un par clave / valor en HashMap.

use std::collections::HashMap;
fn main(){
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   println!("{:?}",stateCodes);
}

El programa anterior crea un HashMap y lo inicializa con 2 pares clave-valor.

Salida

{"KL": "Kerala", "MH": "Maharashtra"}

Ilustración: len ()

Devuelve el número de elementos del mapa.

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   println!("size of map is {}",stateCodes.len());
}

El ejemplo anterior crea un HashMap e imprime el número total de elementos que contiene.

Salida

size of map is 2

Ilustración - get ()

Devuelve una referencia al valor correspondiente a la clave. El siguiente ejemplo recupera el valor de la clave KL en HashMap.

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   println!("size of map is {}",stateCodes.len());
   println!("{:?}",stateCodes);

   match stateCodes.get(&"KL") {
      Some(value)=> {
         println!("Value for key KL is {}",value);
      }
      None => {
         println!("nothing found");
      }
   }
}

Salida

size of map is 2
{"KL": "Kerala", "MH": "Maharashtra"}
Value for key KL is Kerala

Ilustración - iter ()

Devuelve un iterador que contiene una referencia a todos los pares clave-valor en un orden arbitrario.

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");

   for (key, val) in stateCodes.iter() {
      println!("key: {} val: {}", key, val);
   }
}

Salida

key: MH val: Maharashtra
key: KL val: Kerala

Ilustración: contains_key ()

Devuelve verdadero si el mapa contiene un valor para la clave especificada.

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   stateCodes.insert("GJ","Gujarat");

   if stateCodes.contains_key(&"GJ") {
      println!("found key");
   }
}

Salida

found key

Ilustración: eliminar ()

Elimina una clave del mapa.

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   stateCodes.insert("GJ","Gujarat");

   println!("length of the hashmap {}",stateCodes.len());
   stateCodes.remove(&"GJ");
   println!("length of the hashmap after remove() {}",stateCodes.len());
}

Salida

length of the hashmap 3
length of the hashmap after remove() 2

HashSet

HashSet es un conjunto de valores únicos de tipo T. Agregar y quitar valores es rápido, y es rápido preguntar si un valor dado está en el conjunto o no. La estructura HashSet se define en el módulo std :: collections. Este módulo debe importarse explícitamente para acceder a la estructura HashSet.

Sintaxis: Creación de un HashSet

let mut hash_set_name = HashSet::new();

El método estático, nuevo , de la estructura HashSet se utiliza para crear un HashSet. Este método crea un HashSet vacío.

La siguiente tabla enumera algunos de los métodos más utilizados de la estructura HashSet.

No Señor Método Firma y descripción
1 insertar()

pub fn insert(&mut self, value: T) -> bool

Agrega un valor al conjunto. Si el conjunto no tenía este valor presente, se devuelve verdadero o falso.

2 len ()

pub fn len(&self) -> usize

Devuelve el número de elementos del conjunto.

3 obtener()

pub fn get<Q:?Sized>(&self, value: &Q) -> Option<&T> where T: Borrow,Q: Hash + Eq,

Devuelve una referencia al valor en el conjunto, si alguno es igual al valor dado.

4 iter ()

pub fn iter(&self) -> Iter

Devuelve un iterador que visita todos los elementos en orden arbitrario. El tipo de elemento del iterador es & 'a T.

5 contiene_clave

pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool

Devuelve verdadero si el conjunto contiene un valor.

6 eliminar()

pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool

Elimina un valor del conjunto. Devuelve verdadero si el valor estaba presente en el conjunto.

Ilustración - insertar ()

Agrega un valor al conjunto. Un HashSet no agrega valores duplicados a la colección.

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();

   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   names.insert("Mohtashim");//duplicates not added

   println!("{:?}",names);
}

Salida

{"TutorialsPoint", "Kannan", "Mohtashim"}

Ilustración: len ()

Devuelve el número de elementos del conjunto.

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   println!("size of the set is {}",names.len());
}

Salida

size of the set is 3

Ilustración - iter ()

Recupera un iterador visitando todos los elementos en orden arbitrario.

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   names.insert("Mohtashim");

   for name in names.iter() {
      println!("{}",name);
   }
}

Salida

TutorialsPoint
Mohtashim
Kannan

Ilustración: get ()

Devuelve una referencia al valor del conjunto, si lo hay, que es igual al valor dado.

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   names.insert("Mohtashim");

   match names.get(&"Mohtashim"){
      Some(value)=>{
         println!("found {}",value);
      }
      None =>{
         println!("not found");
      }
   }
   println!("{:?}",names);
}

Salida

found Mohtashim
{"Kannan", "Mohtashim", "TutorialsPoint"}

Ilustración - contiene ()

Devuelve verdadero si el conjunto contiene un valor.

use std::collections::HashSet;

fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");

   if names.contains(&"Kannan") {
      println!("found name");
   }  
}

Salida

found name

Ilustración: eliminar ()

Elimina un valor del conjunto.

use std::collections::HashSet;

fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   println!("length of the Hashset: {}",names.len());
   names.remove(&"Kannan");
   println!("length of the Hashset after remove() : {}",names.len());
}

Salida

length of the Hashset: 3
length of the Hashset after remove() : 2