How do I find the index of an element in an array, vector or slice?

Rust

Rust Problem Overview


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.

Rust Solutions


Solution 1 - Rust

I think you should look at the position method instead.

fn main() {
    let test = vec!["one", "two", "three"];
    let index = test.iter().position(|&r| r == "two").unwrap();
    println!("{}", index);
}

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.

Solution 2 - Rust

TLDR Use an iterator with the position method, the Rust docs shows a good example.


No, it's because indices are usize, not i32. 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 use usize.

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 an i32, 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCaballeroView Question on Stackoverflow
Solution 1 - RustMathieu DavidView Answer on Stackoverflow
Solution 2 - RustDK.View Answer on Stackoverflow