当 header 行中可能没有最后一个列名时,使用 Serde 反序列化 CSV
Deserializing a CSV with Serde when the header row may not have the last column name in it
我正在使用 csv
和 serde
crate 反序列化 csv 文件。问题是最后一个字段实际上是一个逗号分隔的列表。
field1,field2,field3
xx, xx, str1, ..., strN
xx, xx,
xx, xx, str1, ..., strM
这就是它在 Rust 中的映射方式,在 reader:
上用 .flexible(true)
读取它
#[derive(Debug, Deserialize)]
struct Row {
field1: isize,
field2: isize,
field3: Vec<String>,
}
如果 CSV 包含 ,field3
和 header 行,一切正常。但是有些文件没有它,我找不到让 serde 仍然填充 Vec
的解决方案。我所能做的就是 #[serde(default)]
让 field3
空着。
这里有一个锈 playground 显示问题:
extern crate csv;
#[macro_use]
extern crate serde_derive;
#[derive(Debug, Deserialize)]
struct Row {
field1: String,
field2: String,
#[serde(default)]
field3: Vec<String>,
}
fn test(str: String) {
let mut reader = csv::ReaderBuilder::new()
.flexible(true)
.from_reader(str.as_bytes());
for row in reader.deserialize() {
if let Ok(row) = row {
let row: Row = row;
println!("{:?}", row);
}
}
}
fn main() {
let csv_data = "
field1,field2,field3
xx,yy,one,two,three
zz,ww,
aa,bb
cc,dd,foo,bar,ban
";
println!("With full header");
test(csv_data.to_string());
let csv_alt_data = "
field1,field2
xx,yy,one,two,three
zz,ww,
aa,bb
cc,dd,foo,bar,ban
";
println!("With incomplet header");
test(csv_alt_data.to_string());
}
在读取行之前手动添加字段 header,使用 headers()
and set_headers()
:
let rdr = reader.headers().unwrap();
if let None = rdr.get(2) {
let mut rdr = rdr.clone();
rdr.push_field("field3");
reader.set_headers(rdr);
}
然而,那又快又脏。
我正在使用 csv
和 serde
crate 反序列化 csv 文件。问题是最后一个字段实际上是一个逗号分隔的列表。
field1,field2,field3
xx, xx, str1, ..., strN
xx, xx,
xx, xx, str1, ..., strM
这就是它在 Rust 中的映射方式,在 reader:
上用.flexible(true)
读取它
#[derive(Debug, Deserialize)]
struct Row {
field1: isize,
field2: isize,
field3: Vec<String>,
}
如果 CSV 包含 ,field3
和 header 行,一切正常。但是有些文件没有它,我找不到让 serde 仍然填充 Vec
的解决方案。我所能做的就是 #[serde(default)]
让 field3
空着。
这里有一个锈 playground 显示问题:
extern crate csv;
#[macro_use]
extern crate serde_derive;
#[derive(Debug, Deserialize)]
struct Row {
field1: String,
field2: String,
#[serde(default)]
field3: Vec<String>,
}
fn test(str: String) {
let mut reader = csv::ReaderBuilder::new()
.flexible(true)
.from_reader(str.as_bytes());
for row in reader.deserialize() {
if let Ok(row) = row {
let row: Row = row;
println!("{:?}", row);
}
}
}
fn main() {
let csv_data = "
field1,field2,field3
xx,yy,one,two,three
zz,ww,
aa,bb
cc,dd,foo,bar,ban
";
println!("With full header");
test(csv_data.to_string());
let csv_alt_data = "
field1,field2
xx,yy,one,two,three
zz,ww,
aa,bb
cc,dd,foo,bar,ban
";
println!("With incomplet header");
test(csv_alt_data.to_string());
}
在读取行之前手动添加字段 header,使用 headers()
and set_headers()
:
let rdr = reader.headers().unwrap();
if let None = rdr.get(2) {
let mut rdr = rdr.clone();
rdr.push_field("field3");
reader.set_headers(rdr);
}
然而,那又快又脏。