'How to find X in a HashMap of HashMaps?
Given that I know ParentId and ChildId, how would I find the UserId if the hashmap is:
HashMap<ParentId, HashMap<ChildId, HashMap<UserId, Foobar>>>
As my knowledge about Rust is pretty basic, I found that the following works but it's quite verbose, as I don't know any better:
match foobar.get(&pid) {
Some(data1) => {
println!("Found 1: {:?}", data1);
match data1.get(&cid) {
Some(data2) => {
println!("Found 2: {:?}", data2);
...and so on
},
_ => println!("Not found")
}
},
_ => println!("Not found")
}
I've also attempted chained get but it's tricky and did not find how to do it correctly:
foobar
.get(pid)?
.get(cid)?
.get(to_find)
What can I try next?
Solution 1:[1]
You can use Option::and_then
to chain operations that return Option<_>
:
let _: Option<&Foobar> = foobar.get(&pid).and_then(|map| map.get(&cid)).and_then(|map| map.get(&to_find));
Example:
use std::collections::HashMap;
fn main() {
let map: HashMap<i32, HashMap<bool, HashMap<String, bool>>> = HashMap::new();
let _: Option<&bool> = map
.get(&123)
.and_then(|map| map.get(&true))
.and_then(|map| map.get("foo"));
}
Your try with ?
is also correct but it'll only work in a function that returns an Option
as it returns None
from the function the expression is in if any value is None
, which is probably the error you're getting.
fn get(map: &HashMap<i32, HashMap<bool, HashMap<String, bool>>>) -> Option<bool> {
map.get(&123)?.get(&true)?.get("foo").cloned()
}
Edit: As @Jmb pointed out in a comment below, another option is to create and immediately call a closure so you can use the ?
operator which could be more readable in certain cases:
let _: Option<&bool> = (|| map.get(&123)?.get(&true)?.get("foo"))();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |