Get first element from HashMap

我与影子孤独终老i 提交于 2019-12-29 08:55:16

问题


I have a HashMap and need to get the first element:

type VarIdx = std::collections::HashMap<u16, u8>;

fn get_first_elem(idx: VarIdx) -> u16 {
    let it = idx.iter();
    let ret = match it.next() {
        Some(x) => x,
        None => -1,
    };
    ret
}

fn main() {}

but the code doesn't compile:

error[E0308]: match arms have incompatible types
 --> src/main.rs:5:15
  |
5 |       let ret = match it.next() {
  |  _______________^
6 | |         Some(x) => x,
7 | |         None => -1,
8 | |     };
  | |_____^ expected tuple, found integral variable
  |
  = note: expected type `(&u16, &u8)`
             found type `{integer}`
note: match arm with an incompatible type
 --> src/main.rs:7:17
  |
7 |         None => -1,
  |                 ^^

how can I fix it?


回答1:


There is no such thing as the "first" item in a HashMap. There are no guarantees about the order in which the values are stored nor the order in which you will iterate over them.

If order is important then perhaps you can switch to a BTreeMap, which preserves order based on the keys.

If you just need to get the first value that you come across, in other words any value, you can do something similar to your original code: create an iterator, just taking the first value:

fn get_first_elem(idx: VarIdx) -> i16 {
    match idx.values().next() {
        Some(&x) => x as i16,
        None => -1,
    }
}

The method values() creates an iterator over just the values. The reason for your error is that iter() will create an iterator over pairs of keys and values which is why you got the error "expected tuple".

To make it compile, I had to change a couple of other things: -1 is not a valid u16 value so that had to become i16, and your values are u8 so had to be cast to i16.

As another general commentary, returning -1 to indicate failure is not very "Rusty". This is what Option is for and, given that next() already returns an Option, this is very easy to accomplish:

fn get_first_elem(idx: VarIdx) -> Option<u8> {
    idx.values().cloned().next()
}

The .cloned() is needed in order to convert the &u8 values of the iterator into u8.




回答2:


HashMap::iter returns an iterator over (&Key, &Value) pairs. What you want is HashMap::values, which produces an iterator that only produces the values of the HashMap.

Note that the order of the values is random. It has nothing to do with the order you put the values in or with the actual value of the values.



来源:https://stackoverflow.com/questions/45194220/get-first-element-from-hashmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!