将字符串的 Vec 拆分为 Vec<Vec<String>>
Splitting a Vec of strings into Vec<Vec<String>>
我正在尝试用 Rust 重新学习数据科学。
我有一个包含分隔符“|”的 Vec<String>
和一个新行“!结束”。
我想得到的结果是 Vec<Vec<String>>
可以放入二维 ND 阵列。
我有这个python代码:
file = open('somefile.dat')
lst = []
for line in file:
lst += [line.split('|')]
df = pd.DataFrame(lst)
SAMV2FinalDataFrame = pd.DataFrame(lst,columns=column_names)
我在这里用 Rust 重新创建了它:
fn lines_from_file(filename: impl AsRef<Path>) -> Vec<String> {
let file = File::open(filename).expect("no such file");
let buf = BufReader::new(file);
buf.lines()
.map(|l| l.expect("Could not parse line"))
.collect()
}
fn main() {
let lines = lines_from_file(".dat");
let mut new_arr = vec![];
//Here i get a lines immitable borrow
for line in lines{
new_arr.push([*line.split("!end")]);
}
// here i get expeected closure found str
let x = lines.split("!end");
let array = Array::from(lines)
我有什么:['1','1','1','end!','2','2','2','!end']
我需要什么:[['1','1','1'],['2','2','2']]
编辑:还有为什么当我使用 turbo fish 时它会在 Stack Overflow 上消失?
我认为您 运行 遇到的部分问题是由于您使用数组的方式。例如,Vec::push
只会添加一个元素,因此您可能希望改用 Vec::extend
。我还将 运行 分为一些空字符串的情况,因为 "!end"
拆分会在子字符串的末尾留下尾随 '|'
。错误非常严重运行ge,我不完全确定闭包是从哪里来的。
let lines = vec!["1|1|1|!end|2|2|2|!end".to_string()];
let mut new_arr = Vec::new();
// Iterate over &lines so we don't consume lines and it can be used again later
for line in &lines {
new_arr.extend(line.split("!end")
// Remove trailing empty string
.filter(|x| !x.is_empty())
// Convert each &str into a Vec<String>
.map(|x| {
x.split('|')
// Remove empty strings from ends split (Ex split: "|2|2|2|")
.filter(|x| !x.is_empty())
// Convert &str into owned String
.map(|x| x.to_string())
// Turn iterator into Vec<String>
.collect::<Vec<_>>()
}));
}
println!("{:?}", new_arr);
我还想出了另一个版本,它应该可以更好地处理您的用例。较早的方法删除了所有空字符串,而这个方法应该在正确处理 "!end"
.
的同时保留它们
use std::io::{self, BufRead, BufReader, Read, Cursor};
fn split_data<R: Read>(buffer: &mut R) -> io::Result<Vec<Vec<String>>> {
let mut sections = Vec::new();
let mut current_section = Vec::new();
for line in BufReader::new(buffer).lines() {
for item in line?.split('|') {
if item != "!end" {
current_section.push(item.to_string());
} else {
sections.push(current_section);
current_section = Vec::new();
}
}
}
Ok(sections)
}
在这个例子中,我使用了 Read
以便于测试,但它也适用于文件。
let sample_input = b"1|1|1|!end|2|2|2|!end";
println!("{:?}", split_data(&mut Cursor::new(sample_input)));
// Output: Ok([["1", "1", "1"], ["2", "2", "2"]])
// You can also use a file instead
let mut file = File::new("somefile.dat");
let solution: Vec<Vec<String>> = split_data(&mut file).unwrap();
我正在尝试用 Rust 重新学习数据科学。
我有一个包含分隔符“|”的 Vec<String>
和一个新行“!结束”。
我想得到的结果是 Vec<Vec<String>>
可以放入二维 ND 阵列。
我有这个python代码:
file = open('somefile.dat')
lst = []
for line in file:
lst += [line.split('|')]
df = pd.DataFrame(lst)
SAMV2FinalDataFrame = pd.DataFrame(lst,columns=column_names)
我在这里用 Rust 重新创建了它:
fn lines_from_file(filename: impl AsRef<Path>) -> Vec<String> {
let file = File::open(filename).expect("no such file");
let buf = BufReader::new(file);
buf.lines()
.map(|l| l.expect("Could not parse line"))
.collect()
}
fn main() {
let lines = lines_from_file(".dat");
let mut new_arr = vec![];
//Here i get a lines immitable borrow
for line in lines{
new_arr.push([*line.split("!end")]);
}
// here i get expeected closure found str
let x = lines.split("!end");
let array = Array::from(lines)
我有什么:['1','1','1','end!','2','2','2','!end'] 我需要什么:[['1','1','1'],['2','2','2']]
编辑:还有为什么当我使用 turbo fish 时它会在 Stack Overflow 上消失?
我认为您 运行 遇到的部分问题是由于您使用数组的方式。例如,Vec::push
只会添加一个元素,因此您可能希望改用 Vec::extend
。我还将 运行 分为一些空字符串的情况,因为 "!end"
拆分会在子字符串的末尾留下尾随 '|'
。错误非常严重运行ge,我不完全确定闭包是从哪里来的。
let lines = vec!["1|1|1|!end|2|2|2|!end".to_string()];
let mut new_arr = Vec::new();
// Iterate over &lines so we don't consume lines and it can be used again later
for line in &lines {
new_arr.extend(line.split("!end")
// Remove trailing empty string
.filter(|x| !x.is_empty())
// Convert each &str into a Vec<String>
.map(|x| {
x.split('|')
// Remove empty strings from ends split (Ex split: "|2|2|2|")
.filter(|x| !x.is_empty())
// Convert &str into owned String
.map(|x| x.to_string())
// Turn iterator into Vec<String>
.collect::<Vec<_>>()
}));
}
println!("{:?}", new_arr);
我还想出了另一个版本,它应该可以更好地处理您的用例。较早的方法删除了所有空字符串,而这个方法应该在正确处理 "!end"
.
use std::io::{self, BufRead, BufReader, Read, Cursor};
fn split_data<R: Read>(buffer: &mut R) -> io::Result<Vec<Vec<String>>> {
let mut sections = Vec::new();
let mut current_section = Vec::new();
for line in BufReader::new(buffer).lines() {
for item in line?.split('|') {
if item != "!end" {
current_section.push(item.to_string());
} else {
sections.push(current_section);
current_section = Vec::new();
}
}
}
Ok(sections)
}
在这个例子中,我使用了 Read
以便于测试,但它也适用于文件。
let sample_input = b"1|1|1|!end|2|2|2|!end";
println!("{:?}", split_data(&mut Cursor::new(sample_input)));
// Output: Ok([["1", "1", "1"], ["2", "2", "2"]])
// You can also use a file instead
let mut file = File::new("somefile.dat");
let solution: Vec<Vec<String>> = split_data(&mut file).unwrap();