12

I am trying to parse a string into a list of floating-point values in Rust. I would assume there is a clever way to do this using iterators and Options; however, I cannot get it to ignore the Err values that result from failed parse() calls. The Rust tutorial doesn't seem to cover any examples like this, and the documentation is confusing at best.

How would I go about implementing this using the functional-style vector/list operations? Pointers on better Rust style for my iterative implementation would be appreciated as well!

"Functional"-style

Panics when it encounters an Err

input.split(" ").map(|s| s.parse::<f32>().unwrap()).collect::<Vec<_>>()

Iterative-style

Ignores non-float values as intended

fn parse_string(input: &str) -> Vec<f32> {
    let mut vals = Vec::new();
    for val in input.split_whitespace() {
        match val.parse() {
            Ok(v) => vals.push(v),
            Err(_) => (),
        }
    }
    vals
}

fn main() {
    let params = parse_string("1 -5.2  3.8 abc");
    for &param in params.iter() {
        println!("{:.2}", param);
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jeff
  • 123
  • 1
  • 6

1 Answers1

14

filter_map does what you want, transforming the values and filtering out Nones:

input.split(" ").filter_map(|s| s.parse::<f32>().ok()).collect::<Vec<_>>();

Note the ok method to convert the Result to an Option.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Chris Morgan
  • 86,207
  • 24
  • 208
  • 215