I need to find an index of an element in a vector of strings. This is what I got so far:
fn main() {
let test: Vec<String> = vec![
"one".to_string(),
"two".to_string(),
"three".to_string(),
"four".to_string(),
];
let index: i32 = test
.iter()
.enumerate()
.find(|&r| r.1.to_string() == "two".to_string())
.unwrap()
.0;
}
It produces an error:
error[E0308]: mismatched types
--> src/main.rs:9:22
|
9 | let index: i32 = test
| ______________________^
10 | | .iter()
11 | | .enumerate()
12 | | .find(|&r| r.1.to_string() == "two".to_string())
13 | | .unwrap()
14 | | .0;
| |__________^ expected i32, found usize
I assume that's because enumerate()
returns a tuple of (usize, _)
(correct me if I'm wrong), but how do I convert usize
to i32
here? If there is a better approach, I'm open to suggestions.
I think you should look at the
position
method instead.You can test it here.
Note that this works for any iterator, so it can be used for vectors, arrays, and slices, all of which produce iterators.
TLDR Use an iterator with the
position
method, the Rust docs shows a good example.No, it's because indices are
usize
, noti32
. In fact,i32
is completely inappropriate for this purpose; it may not be large enough, and there's no reason for it to be signed. Just useusize
.Some other notes: calling
to_string()
is not free, and you don't need it for the comparison; you can compare string slices just fine!Also, if you really want to turn a
usize
into ani32
, you can do that with a cast:x as i32
, though this will not produce an error on over- or under-flow (i.e. the result may be negative).All that said, as noted in Mathieu David's answer, there's a
position
method on iterators that does what you want.