Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterating over the values in a HashTrieMap #10

Closed
Qqwy opened this issue Feb 22, 2018 · 1 comment
Closed

Iterating over the values in a HashTrieMap #10

Qqwy opened this issue Feb 22, 2018 · 1 comment

Comments

@Qqwy
Copy link

Qqwy commented Feb 22, 2018

When wanting to update a single value in the HashMap, we just call insert with the new value (and the same key that already was there). Of course, a wrapper could be written to only insert if the key already exists; this is simple to do for the user (although it might be a worthwhile addition to HashTrieMap's API as well, because it is a very common operation.)

However, when I want to update all of the values, I am out of luck: It is not possible to get a multable iterator to the values or (key, value)-pairs with the current API. Is this a restriction by the underlying data structure? Or is this something that could be improved? (Or is it already possible now and did I loverlook it?)

@orium
Copy link
Owner

orium commented Feb 22, 2018

Being able to actually mutate the values of the map would make the data structure non-persistent (i.e. previous versions of the data structure would be changed).

The recommended way to do this is by making an entirely new map:

let map: HashTrieMap<&str, i32> =
    HashTrieMap::new()
        .insert("a", 0)
        .insert("b", 1);

let map_updated: HashTrieMap<&str, i32> = map.iter().map(|(&k, &v)| {
    (k, v + 1)
}).collect();

However, this would require you to clone/copy the keys/values.

There is, of course, a way to cheat with interior mutability. You can have the values wrapped around a Cell/RefCell/Mutex:

let map =
    HashTrieMap::new()
        .insert("a", RefCell::new(0))
        .insert("b", RefCell::new(1));

for (_, v) in map.iter() {
    let mut mut_v = v.borrow_mut();
    *mut_v = *mut_v + 1;
}

Keep in mind that previous versions of the map will also change.

@orium orium closed this as completed Feb 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants