Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding filter_map in rust

Tags:

rust

I am trying to get ages of all Person who has some second name. I was able to do it using filter and map separately as below, But I am wondering if we can use filter_map in rust.

But I am unable to figure it out.

struct Person {
    pub first_name: String,
    pub last_name: Option<String>,
    pub age: i32,
}


fn main() {
    let mut persons: Vec<Person> = Vec::new();
    persons.push(Person {
        first_name: "Asnim".to_string(),
        last_name: None,
        age: 1,
    });
    persons.push(Person {
        first_name: "Fahim".to_string(),
        last_name: Some("Ansari".to_string()),
        age: 2,
    });
    persons.push(Person {
        first_name: "Shahul".to_string(),
        last_name: None,
        age: 6,
    });
    persons.push(Person {
        first_name: "Mujeeb".to_string(),
        last_name: Some("Rahuman".to_string()),
        age: 6,
    });

    let ages_of_people_with_second_name_using_seperate_filter_map: Vec<i32> = persons
        .iter()
        .filter(|p| p.last_name.is_some())
        .map(|p| p.age)
        .collect();

    println!("{:?}", ages_of_people_with_second_name)
}
like image 781
Asnim P Ansari Avatar asked Dec 03 '22 17:12

Asnim P Ansari


1 Answers

Yep. If you read the documentation for filter_map you'll realize how close you are. Could even use Option's map to help you out

Like:

let ages_of_people_with_second_name_using_seperate_filter_map: Vec<i32> = persons
        .iter()
        .filter_map(|p| p.last_name.map(|_| p.age))
        .collect();

Or a simpler way, using the match pattern:

let ages_of_people_with_second_name_using_seperate_filter_map: Vec<i32> = persons
        .iter()
        .filter_map(|p| match p.last_name { 
           Some(_) => Some(p.age),
           None => None
        })
        .collect();
like image 81
Murillo Avatar answered Jan 12 '23 23:01

Murillo