csv - 解析 TSV 文件 (ASCII) 的惯用方式
问题描述
我需要解析包含制表符分隔数字的文件,我也知道总是只有两个。由于我的文件可能高达几 GB,我想知道我当前的解析方法是否正确。考虑到我的尺寸固定,看起来我可以让地图更快,但我找不到如何做。
use std::io::{self, prelude::*, BufReader};
type Record = (u32, u32);
fn read(content: &[u8]) -> io::Result<Vec<Record>> {
Ok(BufReader::new(content)
.lines()
.map(|line| {
let nums: Vec<u32> = line
.unwrap()
.split("\t")
.map(|s| s.parse::<u32>().unwrap())
.collect();
(nums[0], nums[1])
})
.collect::<Vec<Record>>())
}
fn main() -> io::Result<()> {
let content = "1\t1\n\
2\t2\n";
let records = read(content.as_bytes())?;
assert_eq!(records.len(), 2);
assert_eq!(records[0], (1, 1));
assert_eq!(records[1], (2, 2));
Ok(())
}
解决方案
如果您的条目只是数字,那么我们可以像这样减少一个内部Vec
分配map
:
use std::io::{self, prelude::*, BufReader};
type Record = (u32, u32);
fn read(content: &[u8]) -> io::Result<Vec<Record>> {
return Ok(BufReader::new(content).lines().map(|line| {
let line = line.unwrap();
let mut pair = line.split("\t").map(|s|s.parse::<u32>().unwrap());
(pair.next().unwrap(), pair.next().unwrap())
}).collect::<Vec<Record>>())
}
fn main() -> io::Result<()> {
let content = "1\t1\n\
2\t2\n";
let records = read(content.as_bytes())?;
assert_eq!(records.len(), 2);
assert_eq!(records[0], (1, 1));
assert_eq!(records[1], (2, 2));
Ok(())
}
您可能想要添加更好的错误处理:)
推荐阅读
- android - NestedScrollview 不适用于 Drawerlayout
- tensorflow - 如何从训练有素的 keras 模型中找到等效的 ONNX 运算符?
- vba - VBA中的索引匹配匹配/vlookup
- jmeter - 如何在 JMeter 中执行线程以完全填充以下场景?
- javascript - Electron.js:如何为一个窗口创建一个单独的下载 webContents.session?
- sql-server - 从哪里获得 Sql server 2019 32 位
- typescript - Angular 12 Chart.js - 无法显示甜甜圈
- postman - Postman - 从 NodeJS 运行的 Newman
- php - 如何在 PHP 的类构造函数中将数组作为参数传递
- kentico - 锁定特定角色/用户对实时站点(但不是暂存站点)的 /admin url 的访问