Hashmap's friends

Store data in an insertion-ordered map

indexmap indexmap-crates.io indexmap-github indexmap-lib.rs cat-data-structures cat-no-std

indexmap offers a hash map that separately keeps track of insertion order and allows you to efficiently iterate over its elements in that order.

use indexmap::IndexMap;

// The indexmap crate in Rust provides a hash table
// where the keys have a consistent order of insertion,
// which is preserved when iterating.
fn main() {
    // Creating an IndexMap
    let mut map = IndexMap::new();

    // Inserting elements
    map.insert("a", 1);
    map.insert("b", 2);
    map.insert("c", 3);

    // Iterating in insertion order
    println!("Iterating over IndexMap in insertion order:");
    for (key, value) in &map {
        println!("{}: {}", key, value);
    }

    // Accessing elements by index
    if let Some((key, value)) = map.get_index(1) {
        println!("Element at index 1: {}: {}", key, value);
    }

    // Using the `entry` API
    map.entry("d").or_insert(4);
    map.entry("a").or_insert(10); // This won't change "a" because it already exists
    println!("IndexMap after using entry API:");
    for (key, value) in &map {
        println!("{}: {}", key, value);
    }
}

Store data in a multimap

multimap multimap-crates.io multimap-github multimap-lib.rs

multimap is implemented as a thin wrapper around std::collections::HashMap. It allows multiple values for a given key.

use anyhow::Result;
use crates_io_api::Category;
use crates_io_api::SyncClient;
use multimap::MultiMap;

// Calls the crates.io API client and retrieve the categories a given crate
// belongs to.
fn get_categories_for_crate(crate_name: &str) -> Result<Vec<Category>> {
    let client = SyncClient::new(
        "my-user-agent (my-contact@domain.com)",
        std::time::Duration::from_millis(1000), // Rate limit interval
    )?;
    // Retrieve the crate's information
    let crt = client.get_crate(crate_name)?;
    Ok(crt.categories)
}

fn main() -> Result<()> {
    let crate_names = vec!["toml", "config", "nom", "pest"];

    let mut m: MultiMap<String, &str> = MultiMap::new();
    for name in crate_names {
        for cat in get_categories_for_crate(name)? {
            // There can be multiple crates in the same category
            // A multimap allows multiple values for the same key
            m.insert(cat.slug, name);
        }
    }

    // Get all values for a given key
    println!(
        "List of crates in the `config` category: {:?}",
        m.get_vec("config")
    );

    // Or iterate over all keys and the key's vector
    for (cat, names) in m.iter_all() {
        println!("Category: {:?}, names: {:?}", cat, names);
    }
    Ok(())
}

slotmap

slotmap slotmap-crates.io slotmap-github slotmap-lib.rs

Use to store collections of objects that need stable, safe references but have no clear ownership otherwise, such as game entities or graph nodes.

slotmap provides three containers with persistent unique keys to access stored values, SlotMap , HopSlotMap and DenseSlotMap. Upon insertion a key is returned that can be used to later access or remove the values. Insertion, deletion and access all take O(1) time with low overhead. Two secondary maps, SecondaryMap and SparseSecondaryMap are also provided that map further objects to the keys created by one of the slot maps.

fn main() {
    todo!();
}

See also

Splay tree