What Are Common Collections in Rust?

 What Are Common Collections in Rust?

What Are Common Collections in Rust?

Common Collections

The standard library of Rust includes a number of very useful data structures called collections. Most other  data types represent one specific value, but collections may contain multiple values. We will discuss three collections that are mostly used in Rust programs:
1. A Vector
2. A String
3. A Hash Map

1. Vector:

Allow us to store a variable number of values next to each other.

2. String:

Is a collection of characters.

3. Hash Map:

Allow us to associate a value with a particular key. That is  a particular implementation of the more general data structure called a map.

STORING LISTS OF VALUES WITH

We’ll look at is Vec<T>, also known as a vector for the first collection.

VECTORS

The vectors permit us to store more than one value in a single data structure that puts all the values next to each other in memory. The Vectors can only store values of the same type. They are useful when we have a list of items.

Creating The Empty Vector:
fn main() {
let v: Vec<i32> = Vec::new():
}
Creating The Vector Containing Values:
fn main() {
let v = vec![1,2,3];
println!(“The First Value is = {},
Second Value is = {},Third Value is
= {} “,v[0], v[1], v[2]);
}

Updating the Vector
fn main() {                          // Generating The Empty Vector and Pushing The Value
let mut v1 = Vec::new();
v1.push(5);
v1.push(6);
v1.push(7);
v1.push(8);
println!(“Empty Vector v1 having no value after

Value pushing in Vector v1 {}, {} , {}, {}”,
v1[0], v1[1], v1[2], v1[3]);
}

fn main() {
// Creating Vector Having Some Value
let mut v = vec![1, 2, 3];
v.push(4);
v.push(5);
v.push(6);
v.push(7);
println!(“The Vector having Value is {}, {}, {}

After Value pushing The Vector v Value is {}, {}, {}, {} “,
v[0], v[1], v[2], v[3], v[4], v[5], v[6]);
}

READING ELEMENTS OF VECTOR:

fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!(“The third element is {}”, third);
match v.get(2) {
Some(third) => println!(“The third element is {}”,
third),
None => println!(“There is no third element.”),
}
}

READING ELEMENTS (PANICKED):

fn main() {
let v = vec![1, 2, 3, 4, 5];
let does_not_exist = &v[100];
let does_not_exist = v.get(100);
}

READING ELEMENTS (Error):

fn main() {
let v = vec![1, 2, 3, 4, 5];
Let first = &v[0];
v.push(6);
println!(“The First Element is: {}, First);
}

ITERATING OVER THE VALUE IN A VECTOR:

fn
main() {
let v = vec![100, 32, 57];
for i in &v {
println!(“{}”,i);
}
}

ITERATING OVER MUTABLE REFERENCE IN A VECTOR:

fn main() {
let v = vec![10, 20, 30];
for i in &mut v6 {
*i += 50;
println!(“{}”,i);
}
}

 USING ENUM TO STORE MULTIPLE

The vectors may only store values which are the same type. This may be TYPE that is accessible; there are definitely use cases for needing to store a list of items of different types.The changeable variants of an enum are defined under the same enum type, so when we required to store elements of a different type in a vector, we can define and use an enum!

STORING UTF-8 ENCODED TEXT WITH STRING

What are Strings?

In Rust, there are two types of strings: String and &str. This is heap allocated, flourishale and not null terminated. The &str is a slice ( &[u8] ) which points to a valid UTF-8 sequence, and can be used to view into a String , just like &[T] is a view into Vec<T> .

There is only one string type in Rust in the core language, which is the string slice str that is usually seen in its borrowed form &str. We have discussed the string slices, which are references to some UTF-8 encoded string data stored elsewhere. For instance, String literals, are stored in the program’s binary and are therefore string slices. 

CREATING THE STRING:

fn main() {
let s = String::new();
println!(“Creating a Empty String: {}”, s);
let data = “initial contents”;
let s = data.to_string();
println!(“The Value of s: {}”, s);
{
// method do works on a literal directly:
let d = String::from(“initial contents);
println!(“The Value of d: {}”, d);
}
}

UPDATING THE STRING:

#![allow(unused_variables)]
fn main() {
let mut s1 = String::from(“foo”);
let s2 = “bar”;
s1.push_str(s2);
println!(“s2 is {}”, s2);

CONCATENATION WITH THE OPERATORS:

fn main(){
let s1 = String::from(“Hello, “);
let s2 = String::from(“world!”);
let s3 = s1 + &s2;
println!(“{}”,s3);
}

 fn main (){
let s1 = String::from(“tic”);
let s2 = String::from(“tac”);
let s3 = String::from(“toe”);
let s = s1 + “-” + &s2 + “-” + &s3;
println!(“{}”,s);
}

CONCATENATION WITH FORMAT MACRO

fn main() {
let s1 = String::from(“tic”);
let s2 = String::from(“tac”);
let s3 = String::from(“toe”);
let s = format!(“{}-{}-{}”, s1, s2, s3);

INDEXING INTO STRINGS:

fn main (){
let s1 = String::from(“hello”);
let h = s1[0];
}
This code will result error:
Rust strings don’t support indexing. But why not? We need to discuss how Rust stores strings in memory to answer the question.

STRING BYTES STORAGE:

fn main (){
let len = String::from(“Hola”).len();
println!(“{}”,len);
{
let len = String::from(“Здравствуйте”).len();
println!(“{}”,len);
}
}

BYTES, SCALAR VALUES & GRAPHEME CLUSTER:

There are three ways to look at strings from Rust’s perspective in UTF-8 :
1. By Bytes
2. By Scalar
3. By Grapheme Cluster 

SLICING STRING:
fn main (){
let hello = “Здравствуйте”;
let s = &hello[0..4];
println!(“{}”,s)
}

ITERATING OVER STRING:
fn main (){
for c in “नमस्ते “.chars(){
println!(“{}”, c);}
{
for b in “नमस्ते “.bytes() {
println!(“{}”, b);}
}
}

H A S H M A P

The mapping of keys of type K to values of type V are being stored in the type HashMap<K, V> . This all has done through a hashing function, which determines how it places these keys and values into memory. When we want to look up data not by using an index, as we can with vectors, but by using a key that can be of any type the Hashmap is useful.

CREATING NEW HASH MAP

use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert(String::from(“Blue”), 10);
scores.insert(String::from(“Yellow”), 50);
for (key, value) in &scores {
println!(“{}: {}”, key, value);
}
println!(“{:?}”, scores);
}

ANOTHER WAY TO CREATING NEW HASH MAP

use std::collections::HashMap;
fn main() {
let teams = vec![String::from(“Blue”), String::from(“Yellow”)];
let initial_scores = vec![10, 50];
let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();
for (key, value) in &scores {
println!(“{}: {}”, key, value);
}
println!(“{:?}”, scores);
}

HASH MAP AND OWNERSHIP

use std::collections::HashMap;
fn main() {
let field_name = String::from(“Favorite color”);
let field_value = String::from(“Blue”);
let mut map = HashMap::new();
map.insert(field_name, field_value);
println!(“{:?}”, map);
}

ACCESSING VALUE IN A HASH MAP

use std::collections::HashMap;
fn main(){
let mut scores = HashMap::new();
scores.insert(String::from(“Blue”), 10);
scores.insert(String::from(“Yellow”), 50);
let team_name = String::from(“Blue”);
let score = scores.get(&team_name);
for (key, value) in &scores {
println!(“{}: {}”, key, value);
}
println!(“{:?}”, score);
}

UPDATING A HASH MAP OVERWRITING THE VALUE:

use std::collections::HashMap;
fn main()
{
let mut scores = HashMap::new();
scores.insert(String::from(“Blue”), 10);
println!(“{:?}”, scores);
scores.insert(String::from(“Blue”), 25);
println!(“{:?}”, scores);
}

UPDATING A HASH MAP INSERTING THE VALUE:

use std::collections::HashMap;
fn main(){
let mut scores = HashMap::new();
scores.insert(String::from(“Blue”), 10);
scores.entry(String::from(“Yellow”)).or_insert(50);
scores.entry(String::from(“Blue”)).or_insert(50);
println!(“{:?}”, scores);
}

UPDATING A HASH MAP UPDATING THE VALUE:

use std::collections::HashMap;
fn main(){
let text = “hello world wonderful world”;
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
}
println!(“{:?}”, map);
}

 

Leave a Comment