从HashMap获取第一个元素

时间:2017-07-19 14:54:18

标签: hashmap iterator rust

我有HashMap,需要获得第一个元素:

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() {}

但代码没有编译:

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,
  |                 ^^

我该如何解决?

2 个答案:

答案 0 :(得分:7)

没有&#34;第一&#34; HashMap中的项目。存储值的no guarantees about the order以及迭代它们的顺序。

如果订单很重要,那么您可以切换到BTreeMap,这会根据密钥保留订单。

如果您只需要获得的第一个值,换句话说任何值,您可以执行类似于原始代码的操作:创建迭代器,只取第一个值:

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

方法values()仅在值上创建迭代器。您的错误的原因是iter()将在成对的键和值上创建迭代器,这就是您收到错误&#34;期望的元组&#34; 的原因。

要进行编译,我必须更改其他一些内容:-1不是有效的u16值,因此必须变为i16,并且您的值为{{ 1}}所以必须被投射到u8

作为另一个一般性评论,返回i16表示失败不是很严重&#34;生锈&#34;。这是-1的用途,并且鉴于Option已经返回next(),这很容易实现:

Option

为了将迭代器的fn get_first_elem(idx: VarIdx) -> Option<u8> { idx.values().cloned().next() } 值转换为.cloned(),需要&u8

答案 1 :(得分:5)

HashMap::iter返回(&Key, &Value)对的迭代器。你想要的是HashMap::values,它产生的迭代器只产生HashMap的值。

请注意,值的顺序是随机的。它与您将值放入的顺序或与值的实际值无关。