← Rust EnglishChapter 08 of 13

Vectors, Strings and HashMaps

## Learning Objectives - Work with Vec (dynamic arrays) - Master String manipulation - Use HashMap for key-value storage - Choose appropriate collection types ## Vectors ### Creating Vectors ```rust fn main() { let v: Vec = Vec::new(); let v = vec![1, 2, 3]; // Using macro let v = vec![0; 5]; // Five zeros } ``` ### Vector Adding Elements ```rust fn main() { let mut v = Vec::new(); v.push(1); v.push(2); v.push(3); v.extend([4, 5, 6]); // Add multiple v.push_str("hello"); // Error: different type } ``` ### Reading Elements ```rust fn main() { let v = vec![1, 2, 3, 4, 5]; let third = v[2]; // Panics if out of bounds let third = v.get(2); // Returns Option<&T> let third = v.get(2).unwrap(); // Returns 3 match v.get(10) { Some(n) => println!("{}", n), None => println!("Not found"), } } ``` ### Vector Iterating ```rust fn main() { let v = vec![1, 2, 3]; // Immutable borrow for i in &v { println!("{}", i); } // Mutable borrow let mut v = vec![1, 2, 3]; for i in &mut v { *i *= 2; // Double each element } } ``` ### Useful Methods ```rust fn main() { let mut v = vec![1, 2, 3, 4, 5]; v.pop(); // Remove and return last v.remove(1); // Remove at index v.insert(0, 10); // Insert at index v.clear(); // Remove all v.len(); // Length v.is_empty(); // Check if empty v.contains(&3); // Check for value v.iter().position(|&x| x == 3); // Find index v.sort(); // Sort (requires PartialOrd) v.reverse(); } ``` ### Using Enum in Vector ```rust fn main() { enum SpreadsheetCell { Int(i32), Float(f64), Text(String), } let row = vec![ SpreadsheetCell::Int(3), SpreadsheetCell::Text(String::from("blue")), SpreadsheetCell::Float(10.12)), ]; } ``` ## Strings ### Creating Strings ```rust fn main() { let s = String::new(); // Empty string let s = "initial".to_string(); // From literal let s = String::from("initial"); // From literal let s = String::with_capacity(10); // Pre-allocated } ``` ### Updating Strings ```rust fn main() { let mut s = String::from("hello"); s.push(' '); // Add char s.push_str("world"); // Add string slice let s1 = String::from("Hello, "); let s2 = String::from("world!"); let s3 = s1 + &s2; // s1 is moved, s2 borrowed // println!("{}", s1); // Error: s1 moved let s1 = String::from("Hello"); let s2 = String::from("world"); let s3 = format!("{} {}", s1, s2); // format! macro } ``` ### String Slices ```rust fn main() { let s = String::from("hello world"); let hello = &s[0..5]; // hello let world = &s[6..11]; // world let hello = &s[..5]; // hello let world = &s[6..]; // world } ``` ### Iterating Over Strings ```rust fn main() { let s = "hello"; for c in s.chars() { println!("{}", c); } for b in s.bytes() { println!("{}", b); } } ``` ### Useful String Methods ```rust fn main() { let s = " hello world "; s.trim(); // Trim whitespace s.to_uppercase(); // UPPERCASE s.to_lowercase(); // lowercase s.len(); // Byte length s.is_empty(); // Check if empty "hello".contains("ell"); // true "hello".starts_with("he"); // true "hello".ends_with("lo"); // true "hello".replace("l", "r"); // herro let parts: Vec<&str> = "a,b,c".split(',').collect(); } ``` ### String from User Input ```rust use std::io; fn main() { let mut input = String::new(); io::stdin().read_line(&mut input) .expect("Failed to read line"); let input = input.trim(); // Remove newline println!("You entered: {}", input); } ``` ## HashMaps ### Creating HashMaps ```rust use std::collections::HashMap; fn main() { let mut map: HashMap = HashMap::new(); let map = HashMap::from([ ("a".to_string(), 1), ("b".to_string(), 2), ]); } ``` ### HashMap Adding Elements ```rust use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert(String::from("Blue"), 10); scores.insert(String::from("Yellow"), 50); // Only insert if key doesn't exist scores.entry(String::from("Blue")).or_insert(20); scores.entry(String::from("Red")).or_insert(30); } ``` ### Accessing Values ```rust use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert(String::from("Blue"), 10); let team = String::from("Blue"); let score = scores.get(&team); // Option<&i32> match scores.get(&team) { Some(s) => println!("Score: {}", s), None => println!("Team not found"), } } ``` ### HashMap Iterating ```rust use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert("Blue", 10); scores.insert("Yellow", 50); // Iterate over key-value pairs for (key, value) in &scores { println!("{}: {}", key, value); } // Iterate over keys for key in scores.keys() { println!("{}", key); } // Iterate over values for value in scores.values() { println!("{}", value); } } ``` ### Updating Values ```rust use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert("Blue", 10); // Overwrite scores.insert("Blue", 25); // Blue: 25 // Only insert if key doesn't exist scores.entry("Yellow").or_insert(50); // Yellow: 50 scores.entry("Yellow").or_insert(100); // Yellow: 50 (unchanged) // Update based on old value let text = "hello world wonderful world"; let mut word_count = HashMap::new(); for word in text.split_whitespace() { let count = word_count.entry(word).or_insert(0); *count += 1; } } ``` ### Removing Entries ```rust use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert("Blue", 10); scores.remove("Blue"); // Remove entry scores.clear(); // Remove all } ``` ## Choosing Collection Types ### Vec vs Array - Use **array** when size is fixed at compile time - Use **Vec** when size may grow or shrink ### String vs &str - Use **&str** (string slice) when you don't need ownership - Use **String** when you need ownership or to build strings ### HashMap vs Vec - Use **HashMap** when you need key-value lookups - Use **Vec** when you need ordered data or indices ### HashSet ```rust use std::collections::HashSet; fn main() { let mut set = HashSet::new(); set.insert(1); set.insert(2); set.insert(3); set.contains(&2); // true set.remove(&1); let a = vec![1, 2, 3]; let b = vec![2, 3, 4]; let intersection: Vec<_> = a.iter().filter(|x| b.contains(x)).collect(); let union: Vec<_> = a.iter().chain(b.iter()).collect(); } ``` ## Summary - Vectors (`Vec`) are dynamic arrays - Use `push` to add, `pop` to remove from end - Use `get` for safe access, `[]` for panicking access - Strings (`String`) are growable, `&str` is a view - Use `format!` to concatenate strings - `HashMap` stores key-value pairs - Use `entry().or_insert()` for insert-if-missing - `HashSet` stores unique values

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →