Rust - Collections


Hashmaps

HashMaps are like unordered maps in C++. Docs.

use std::collections::HashMap;

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

    // All keys must be of the same type and all values must be of the same type
    occur.insert(String::from("Blue"), 12);
    occur.insert(String::from("Red"), 5);

    let teams = vec![String::from("Blue"), String::from("Pink")];
    let scores = vec![5, 78];

    let mut scores: HashMap<_, _> =
        teams.into_iter().zip(scores.into_iter()).collect();
        // Teams and scores becoming iterators. Zip combines them into _, _ iterator
        // Collect transforms the iterator into a container, in this case, a HashMap

    // Hash maps copy for copy traited types, moved for others
    let key = String::from("Moved Key");
    let value = String::from("Moved Value");

    let mut map = HashMap::new();
    map.insert(key, value); // key and value are now invalid identifiers

    // --- Accessing Elements --- //
    let blue_score = scores.get("Blue");  // Wrapped in Some -> Some(&7)

    let team_name = String::from("Pink");
    let pink_score = scores.get(&team_name);  // Some(&78)

    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }

    // --- Updating --- //
    // Overwriting
    scores.insert(String::from("Blue"), 12);
    // Update if key does not exist
    scores.entry(String::from("Purple")).or_insert(42);
    // Update an existing value
    let mut map = HashMap::new();
    let text = "apples pies are full of pies";
    for word in text.split_whitespace() {
        let count = map.entry(word).or_insert(0);  // count is a mutable reference
        *count += 1
    }
    println!("{:?}", map); // HashMaps do NOT retain order

}

String

Strings are encoded as UTF-8 characters in Rust, thus they are a bit weird. They cannot be indexed into since UTF-8 is variable lengthen. Docs.

fn main() {
    // Initialize
    let mut s = String::new();
    let const_str = "str, not String";
    s = const_str.to_string();
    let mut s = String::from("hello");
    let s2 = String::from(" This is Daltie!");

    // Append
    s.push_str(" world");
    s.push('!');
    let s3 = s + &s2; // s has been moved and can no longer be used
    let s1 = String::from("Hello World!");
    let s3 = format!("{} {}", s1, s2);

    // Iterating Over
    for c in s3.chars() {
        println!("{}" ,c);
    }
}

Vector

Just like a C++ vector. Docs.

fn main() {
    // With type annotation
    let _v: Vec = Vec::new();
    // With type deduction (vec! macro)
    let mut v = vec![1, 2, 3];
    for i in 5..8 {
        v.push(i);
        
    }

    // --- Read element --- //
    // & [index], causes a panic if accessing memory outside of vector
    let _third: &i32 = &v[2];
    let fourth = &v[3];
    let _fourth_copy = v[3]; // Copy of the fourth element
    println!("Forth: {}", fourth);
    // .get() returns Option<&T>
    match v.get(4) {
        Some(fifth) => println!("The fifth element is: {}", fifth),
        None => println!("There is no fifth element!"),
    }

    // -- Iterating -- //
    for i in &v {
        println!("{}", i);
    }
    // Mutable
    for i in &mut v {
        *i += 1; // Dereference operator required to update

    }

    // --- Multi-Type Vector Hack --- //
    enum Colors {
        Rgb(i32),
        Grayscale(f32),
    }
    let _pixels = vec![
        Colors::Rgb(255),
        Colors::Grayscale(3.5),
    ];

    // --- Useful Methods --- //
    // Length
    let _len = v.len();
    // Clear
    v.clear();
    // Insert
    v.insert(0, 4); // Index, value
    // Remove
    let _value = v.remove(0); // Index
    // Push/Pop back
    v.push(5);
    let _value = v.pop();
}