Rust Map Guide: In-depth understanding and easy application

2024.01.11

Today we will talk about map knowledge in Rust. Like other languages, Map usually refers to a data structure and a series of operations, used to map a set of values ​​to another set of values ​​or perform certain operations, that is What we often call key-value pairs. Next, let’s discuss the basic usage of map in Rust, common operations, and some useful techniques.

What is map?

Map is a very important data structure in Rust. Similar to other languages, it is also a collection of key-value storage. It allows you to associate a key with a value and then easily retrieve the value by key. The following is a simple example. In Rust, map is usually implemented through std::collections::HashMap.

use std::collections::HashMap;

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

    scores.insert("Alice", 100);
    scores.insert("Bob", 90);
    scores.insert("Charlie", 95);

    let alice_score = scores.get("Alice");

    match alice_score {
        Some(score) => println!("Alice's score is: {}", score),
        None => println!("Alice's score is not available."),
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

operation result:

Alice's score is: 100

[Done] exited with code=0 in 0.689 seconds
  • 1.
  • 2.
  • 3.

In the above example, a HashMap named scores is created and three key-value pairs are inserted into it. Use the get method to retrieve "Alice's" score.

  • Among them, match alice_score { ... } is used to match the value of alice_score and execute different code blocks based on the matching results.
  • Some(score) => println!("Alice's score is: {}", score): This is a matching branch. It checks if alice_score contains Some value.
  • None => println!("Alice's score is not available."): This is another matching branch to handle the case where alice_score is None.

These matching rules are quite easy to use in the Rust language.

Basic operations

1. Insert and update values

If you want to insert a new key-value pair into a HashMap, you can use the insert method. If the key already exists, it will overwrite the value.

scores.insert("Alice", 105);  // 更新Alice的分数
scores.insert("Eve", 80);      // 插入新的键值对
  • 1.
  • 2.

2. Get the value

To get the value in HashMap, you can use the get method, which is very similar to Java. If the key does not exist, it returns an Option.

// let alice_score = scores.get("test"); // 键不存在,将会打印出 None
let alice_score = scores.get("Alice");
match alice_score {
    Some(score) => println!("Alice's score is: {}", score),
    None => println!("Alice's score is not available."),
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

3. Delete value

You can also delete key-value pairs in a HashMap by using the remove method.

scores.remove("Bob");
  • 1.

4.Traverse

In addition to the above addition, deletion and modification operations, there is another important thing. If you traverse all key values ​​​​in the HashMap, use an iterator here.

use std::collections::HashMap;

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

    scores.insert("Alice", 100);
    scores.insert("Bob", 90);
    scores.insert("Charlie", 95);
    scores.insert("Alice", 105);

    // 遍历
    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

Traversal results:

Charlie: 95
Alice: 105
Bob: 90

[Done] exited with code=0 in 0.521 seconds
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

In addition to the common operations introduced above, HashMap actually provides many useful methods, such as finding whether a key exists, getting a set of keys, getting a set of values, and so on. In actual development, these methods can be used flexibly as needed and are very convenient.

5.Default value

First, let's look at the first one, the default value. This function is that if the key does not exist, you can use the entry method to set the default value.

let charlie_score = scores.entry("Charlie").or_insert(0);
  • 1.

6.Update value

In addition, you can also use the entry method to update the value, which is even more interesting. It allows you to perform operations based on the original value, which is quite fun to use, right?

let bob_score = scores.entry("Bob").or_insert(0);
*bob_score += 5;
  • 1.
  • 2.

7. Sort

Last one, if you need to sort the HashMap by keys or values, you can extract them into a Vec and then use the sort method to sort.

let mut score_vec: Vec<(&str, &i32)> = scores.iter().collect();
score_vec.sort_by(|a, b| b.1.cmp(a.1));  // 按值降序排序
  • 1.
  • 2.
  • scores.iter() is the iter method using HashMap, returning an iterator that can be used to traverse the key-value pairs in the HashMap.
  • The collect method is used to collect the elements in the iterator into a container. Here, the key-value pairs are collected into the score_vec vector.

Then now the score_vec vector contains the key-value pairs in the HashMap, and then the sort_by method is used to sort the elements in the vector. In fact, it is done through a closure, which accepts two parameters a and b, which respectively represent two elements in the vector. Each element is a tuple containing a key and a value.

Element comparison uses the cmp method, which returns a sorting order. For integers, it can be Ordering::Less, Ordering::Equal or Ordering::Greater, which means "less than", "equal to" or "greater than" respectively.

at last

To summarize, HashMap in Rust is a powerful data structure for storing and manipulating key-value pairs. Today we mainly introduce common usage, common operations and some tips. I hope it will be helpful to you.