如何简化将文本文件解析为值向量的过程?
How to simplify parsing a text file to a vector of values?
我是 Rust 的新手,我正在尝试找到最简单有效的解析文本文件的方法,例如:
1
2
3
4
5
到我代码中的 u32 向量。现在我有一个将文件读取为字符串的解决方案(它正好来自 rustbyexample.com,我稍微改变了它):
let path = Path::new("J:/IntegerArray.txt");
let display = path.display();
let mut file = match File::open(&path)
{
Err(why) => panic!("couldn't open {}: {}", display, why.desc),
Ok(file) => file,
};
let data_str = match file.read_to_string()
{
Err(why) => panic!("couldn't read {}: {}", display, why.desc),
Ok(string) =>
{
string
}
};
然后我解析它:
let mut data : Vec<u32> = vec![];
for str in data_str.lines_any()
{
data.push(match str.trim().parse() { Some(x) => x, None => continue, } );
}
但是我认为有一种解决方案可以在一行中完成而无需循环,例如:
let mut data : Vec<u32> = data_str.lines_any().<SOME MAGIC>.collect();
也许可以用 map 和 filter 来完成,但主要问题是将 Option 解包到 u32,因为我看不到如何同时过滤掉 Nones 和解包到 u32。否则,只过滤而不展开会导致再次进一步检查它们。是否可以采用单线解决方案?它会是一个有效的解决方案吗?
filter_map
就是您要找的:
let data: Vec<u32> = data_str.lines_any().filter_map(|s| s.trim().parse()).collect();
我是 Rust 的新手,我正在尝试找到最简单有效的解析文本文件的方法,例如:
1
2
3
4
5
到我代码中的 u32 向量。现在我有一个将文件读取为字符串的解决方案(它正好来自 rustbyexample.com,我稍微改变了它):
let path = Path::new("J:/IntegerArray.txt");
let display = path.display();
let mut file = match File::open(&path)
{
Err(why) => panic!("couldn't open {}: {}", display, why.desc),
Ok(file) => file,
};
let data_str = match file.read_to_string()
{
Err(why) => panic!("couldn't read {}: {}", display, why.desc),
Ok(string) =>
{
string
}
};
然后我解析它:
let mut data : Vec<u32> = vec![];
for str in data_str.lines_any()
{
data.push(match str.trim().parse() { Some(x) => x, None => continue, } );
}
但是我认为有一种解决方案可以在一行中完成而无需循环,例如:
let mut data : Vec<u32> = data_str.lines_any().<SOME MAGIC>.collect();
也许可以用 map 和 filter 来完成,但主要问题是将 Option 解包到 u32,因为我看不到如何同时过滤掉 Nones 和解包到 u32。否则,只过滤而不展开会导致再次进一步检查它们。是否可以采用单线解决方案?它会是一个有效的解决方案吗?
filter_map
就是您要找的:
let data: Vec<u32> = data_str.lines_any().filter_map(|s| s.trim().parse()).collect();