How to convert Vec<Vec<&str>> into a Vec<MyStruct>

I'm relatively new to Rust, and I'm wondering if there's a better way to dump a Vec<Vec<&str>> into a Vec<MyStruct>.

Here's a simplification of my current working code (and link to a playground version). In my actual code, the Vec<Vec<&str>> is built from a scraped HTML table (hence the string values).

I've mostly worked in Python ... which may or may not be apparent in the code below.

const NUM_DATA: u16 = 2; // Actually more like ~400, and it does not change.

struct Data {
    rank: u16,
    name: String,
    data: f32,
    // Actually total of 22 fields, mostly floats, some ints
}

fn main() {
    let mut my_data: Vec<Data> = Vec::with_capacity(NUM_DATA as usize);
    let strings = vec![vec!["1", "Foobar", "98.6"], vec!["2", "Baz", "32.0"]];

    for s in strings {
        // It's safe to assume that both vecs are exactly the length I'm expecting
        // and that each element will safely parse (and, if not, panic is appropriate)
        my_data.push(Data {
            rank: s[0].parse::<u16>().unwrap(),
            name: s[1].to_string(),
            data: s[2].parse::<f32>().unwrap(),
            // ...
            // data22: s[21].parse::<f32>().unwrap(),
        })
    }
    my_data.into_iter().for_each(|d| {
        println!("Rank: {}", d.rank);
        println!("Name: {}", d.name);
        println!("Data: {}", d.data);
        println!("----------------");
    });
}

maybe you could use from_iter():

    let strings = vec![vec!["1", "Foobar", "98.6"], vec!["2", "Baz", "32.0"]];

    let iter = strings.iter().map(|element| Data {
        rank: element[0].parse::<u16>().unwrap(),
        name: element[1].to_string(),
        data: element[2].parse::<f32>().unwrap(),
    });

    let my_data = Vec::from_iter(iter);

I personally prefer the functional style:

let my_data = strings.iter().map(|string| {
        Data {
            rank: string[0].parse::<u16>().unwrap(),
            name: string[1].to_string(),
            data: string[2].parse::<f32>().unwrap(),
            // ...
            // data22: s[21].parse::<f32>().unwrap(),
        }
    }).collect::<Vec<Data>>();
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.