'Idiomatic Rust for Vec<Vec<String>> filter

Very new to programming and for some reason i chose rust to start with but i digress...

Current code to take a reference to a vec of vec strings, compare one 'Column' against some array and return the row and a truncated version of the row.

The below compiles, but i keep re-using this same logic across all my functions and would be really useful to just have some kind of closure.

fn niacs(vec:&Vec<Vec<String>>, naics: Vec<&str> ) -> (Vec<Vec<String>>,Vec<Vec<String>>) {
    let mut return_vec_truncated = vec![];
    let mut return_vec_full = vec![];
    let mut contains_naice = false;

    
    for i in vec.iter() {
        for naic in naics.iter(){
            if i[31] == *naic {
                contains_naice = true;
            }
        
            if contains_naice {
                let x = info_wanted(&i);
                return_vec_truncated.push(x);
                return_vec_full.push(i.clone());
            }
            contains_naice = false;
    }
}
     (return_vec_full, return_vec_truncated)
}

What i would like to be able to do is write something like:

let x = vec.iter().map(|x| x.iter()).filter(|x| x != naics);

The problem is.. I don't want to map across all of the elements per say, i just want to make across one column within the inner vec, which is column 31.

Sample Vec of Vec:

["471", "001020887", "", "1SNH0", "", "A", "Z2", "20020312", "20210711", "20200731", "20200731", "BENCHMARK INTERNATIONAL, INC", "", "", "", "5025 PIRATES COVE RD", "", "JACKSONVILLE", "FL", "32210", "8309", "USA", "04", "19990208", "1231", "http://www.bmiint.com", "2L", "VA", "USA", "0005", "27~2X~A5~QF~XS", "541611", "", "0002", "541611Y~541690Y", "0000", "", "N", "", "5025 PIRATES COVE RD", "", "JACKSONVILLE", "32210", "8309", "USA", "FL", "ANNA", "", "MCKENZIE", "", "5025 PIRATES COVE RD", "", "JACKSONVILLE", "32210", "8309", "USA", "FL", "4437170460", "", "", "", "[email protected]"], ["472", "001021310", "", "94867", "", "A", "Z2", "19980424", "20210323", "20200323", "20200323", "CHURCHILL CORPORATION", "", "", "", "344 FRANKLIN ST", "", "MELROSE", "MA", "02176", "1825", "USA", "05", "19480101", "0731", "", "2L", "MA", "USA", "0002", "2X~MF", "332322", "", "0001", "332322Y", "0000", "", "Y", "", "P.O.BOX 761038", "", "MELROSE", "02176", "1825", "USA", "MA", "MARSHALL", "W", "SCHERMERHORN", "", "P.O. BOX 761038", "344 FRANKLIN STREET", "MELROSE", "02176", "", "USA", "MA", "7816654700", "", "", "7816625291", "[email protected]"]]



Solution 1:[1]

First, to confirm that I'm not overlooking something:

Your code is equal to

fn niacs(vec: &Vec<Vec<String>>, naics: Vec<&str>) -> (Vec<Vec<String>>, Vec<Vec<String>>) {
    let mut return_vec_truncated = vec![];
    let mut return_vec_full = vec![];
    for i in vec.iter() {
        for naic in naics.iter() {
            if i[31] == *naic {
                return_vec_truncated.push(info_wanted(&i));
                return_vec_full.push(i.clone());
            }
        }
    }
    (return_vec_full, return_vec_truncated)
}

and the contains_naice is unnecessary? Except for contains_naice, I think your code easy to read and plenty idiomatic.

If you absolutely want to write it with iterators, you can use flat_map and unzip:

fn niacs(vec: &Vec<Vec<String>>, naics: Vec<&str>) -> (Vec<Vec<String>>, Vec<Vec<String>>) {
    vec.iter()
        .flat_map(|i| naics.iter().filter(|naic| i[31] == **naic).map(move |_| i))
        .map(|i| (i.clone(), info_wanted(&i)))
        .unzip()
}

Though I do wonder: Is that actually what you wanted? Do you really want one copy of i per matching naic? Or do you maybe want one copy of i if any of the naics match?

fn niacs(vec: &Vec<Vec<String>>, naics: Vec<&str>) -> (Vec<Vec<String>>, Vec<Vec<String>>) {
    vec.iter()
        .filter(|i| naics.iter().any(|naic| i[31] == *naic))
        .map(|i| (i.clone(), info_wanted(&i)))
        .unzip()
}

(The equal iterative code would have a break inside the if.)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1