代码之家  ›  专栏  ›  技术社区  ›  punkbit

如何在HashMap的HashMap中找到X?

  •  0
  • punkbit  · 技术社区  · 2 年前

    鉴于我知道ParentId和ChildId,如果hashmap是:

    HashMap<ParentId, HashMap<ChildId, HashMap<UserId, Foobar>>>
    

    由于我对锈病的了解非常基础,我发现下面的方法很有效,但非常冗长,因为我不知道还有什么更好的方法

    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")
    }
    

    我也尝试过链式get,但这很棘手,没有找到正确的方法

    foobar
            .get(pid)?
            .get(cid)?        
            .get(to_find)
    

    任何提示都将不胜感激,谢谢!

    1 回复  |  直到 2 年前
        1
  •  1
  •   Dogbert    2 年前

    你可以用 Option::and_then 连锁经营 Option<_> :

    let _: Option<&Foobar> = foobar.get(&pid).and_then(|map| map.get(&cid)).and_then(|map| map.get(&to_find));
    

    例子:

    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"));
    }
    

    Playground


    你的尝试 ? 也是正确的,但它只在返回 Option 当它回来的时候 None 从函数中,如果有任何值 没有一个 ,这可能就是你的错误。

    fn get(map: &HashMap<i32, HashMap<bool, HashMap<String, bool>>>) -> Option<bool> {
        map.get(&123)?.get(&true)?.get("foo").cloned()
    }