I have a file ratings.csv which has rows such as:
Foo, 0, 1, 5, 3, -2, ...
Bar, 0, 4, 5, -3, ...
Each row starts with a customer name and has info about ratings afterwards. I want to create a 2d vector, in which each item is a row, and each item in that row is a user rating, stored as an i32
. I'm also struggling to manipulate it such that the customer name isn't inside the subvector, as the subvectors should only contain i32
.
I've tried the read_to_string()
and .split(",")
method but I can't find a way to transpose all the numbers to i32
from &str
.
It may be possible to transpose each value individually with the .parse::<i32>()
method, but there is probably a more efficient way.
CodePudding user response:
Usually, parsing is done via specialized libraries, for security reasons.
You can of course do it by hand, especially if your input is as easy as CSV. But if you want to do it manually, then yes, you need to parse every single value.
I personally would use the csv
crate. It has built-in serde
support, meaning, you can directly define the type you want to write the data into:
ratings.csv:
Foo,0,1,5,3,-2
Bar,0,4,5,-3,3
main.rs:
use std::{error::Error, fs::File};
type Rating = (String, Vec<i32>);
fn main() -> Result<(), Box<dyn Error>> {
let file = File::open("ratings.csv")?;
let mut reader = csv::ReaderBuilder::new()
.has_headers(false)
.from_reader(file);
for result in reader.deserialize() {
let record: Rating = result?;
println!("{}: {:?}", record.0, record.1);
}
Ok(())
}
Foo: [0, 1, 5, 3, -2]
Bar: [0, 4, 5, -3, 3]