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?
To get the first element of a Map , use destructuring assignment, e.g. const [firstKey] = map. keys() and const [firstValue] = map. values() . The keys() and values() methods return an iterator object that contains the Map's keys and values.
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().copied().next()
}
The .copied()
is needed in order to convert the &u8
values of the iterator into u8
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With