HashMap unexpected/unknown behavior

So, I've this code:

fn main() {
    // * Use a HashMap for the furniture store stock
    let mut store_stock: HashMap<String, u32> = HashMap::new();
    // * The store has:
    //   * 5 Chairs
    //   * 3 Beds
    //   * 2 Tables
    //   * 0 Couches
    store_stock.insert("Chair".to_owned(), 5);
    store_stock.insert("Bed".to_owned(), 3);
    store_stock.insert("Table".to_owned(), 2);
    store_stock.insert("Couche".to_owned(), 0);

    println!("{:?}\n\n", store_stock);

    // * Print the name and number of items in stock for a furniture store
    // * If the number of items is 0, print "out of stock" instead of 0
    store_stock.iter().for_each(|(item, qty)| {
        if qty == &0_u32 {
            println!("We don't have any {:?} left", item);
        } else {
            println!("We have {:?} {:?}s", qty, item)
        }
    });
    // * Print the total number of items in stock
    let total_stock = store_stock.iter().fold(0, |acc, (_item, qty)| acc + qty);
    println!("total stock = {:?} items", total_stock);
}

Now, when I run it, I get the following:

{"Table": 2, "Couche": 0, "Bed": 3, "Chair": 5}


We have 2 "Table"s
We don't have any "Couche" left
We have 3 "Bed"s
We have 5 "Chair"s
total stock = 10 items

That is, the elements of the HashMap don't appear to be inserted in the way the insertion process has been coded, and I would expected this result:

{"Chair": 5, "Bed": 3, "Table": 2, "Couche": 0}

What am I missing?
On the side: is there any way to get rid of the quotation marks in the output?
Thanks

A hash table is an inherently (pseudo-)randomized data structure. Unless it's implemented specifically in a way that it keeps track of key order, it doesn't (it can't).

Use the Display impl, not Debug: println!("We have {} {}s", qty, item);

2 Likes

A BTreeMap (along with some state to track insertion order) may suit your use case better.

Playground.

On second thought, the benefits of a map (looking up by name) are pretty much thrown out by this approach, so you might has well use a Vec<String, u32> if it actually suits your needs.

Sorry for the noise.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.