Optional Skip
About
CSV๋ฅผ ์ฝ์ด์ line, cell ๋ณ๋ก ๋ถ๋ฆฌํด์ ์ถ๋ ฅํ๋ ํ๋ก๊ทธ๋จ์ ๋ง๋ค๊ณ ์๋ค๊ฐ ๋ค์๊ณผ ๊ฐ์ ์ํฉ์ ๋ง์ฃผํ์๋ค.
๋ค์ ์ฝ๋๋ CSV ๋ฌธ์์ด ์คํธ๋ฆผ์ ์ฝ์ด์ ์ถ๋ ฅํ๋ ์ฝ๋์ธ๋ฐ, parse_csv_document
๋ ๋ ๋ฒ์งธ ์ธ์๋ก header
bool ๊ฐ์ ๋ฐ์ ์ ํ์ ์ผ๋ก CSV ํ
์ด๋ธ ํค๋๋ฅผ ์คํตํ ์ ์๋ ๊ธฐ๋ฅ์ ๊ฐ๊ณ ์๋ค.
use std::io::{BufRead, Result};
fn parse_csv_document(src: impl BufRead, header: bool) -> Result<Vec<Vec<String>>> {
let mut lines = src.lines();
if !header {
// ?
}
lines
.map(|line| {
println!("line: {:?}", line);
line.map(|line| {
line.split(",")
.map(|entry| String::from(entry.trim()))
.collect()
})
})
.collect()
}
const CSV_STRING: &str = "KO-KR,KO-KR Alphabet,EN Alphabet,
๊ธฐ์ญ,ใฑ,a
๋์,ใด,b
๋๊ทฟ,ใท,c
";
fn main() {
let res = parse_csv_document(CSV_STRING.as_bytes(), false);
println!("{:?}", res);
}
์ด๋ฐ ์ํฉ์์ if header
์กฐ๊ฑด ์์ ์ด๋ค ์ฝ๋๋ฅผ ๋ฃ์ด์ผ ํ ๊น?
1. lines.next()
๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ด๋ค. next()
๋ mutableํ๊ฒ iterable๋ฅผ ๋ฐ์์(&mut
) ๋ค์ line์ผ๋ก ๋์ด๊ฐ๋๋ก ํ๋ ๋ฉ์๋์ด๋ค.
if !header {
lines.next();
}
ํ์ง๋ง ํ ๋ฒ๋ง ์คํ๋๋ค๋ ๊ฒ์ด ๋ง์์ ๋ค์ง๋ ์์๋ค.
2. lines.skip(N)
์ฌ์ค ์ด๊ฒ ๋ ๊ฑฐ๋ผ๊ณ ์๊ฐํ๋ค. ๊ทธ๋ฐ๋ฐ ์ฌ์ค skip()
์ ๊ธฐ์กด์ lines
๋ฅผ mutate ํ์ง ์๊ณ , N๋งํผ ์คํตํ ์๋ก์ด iterator๋ฅผ ๋ฐํํ๋ค.
๊ทธ๋ฆฌ๊ณ move๊ฐ ์ผ์ด๋๊ธฐ๋ ํด์ ํด๋น ์ฝ๋ ์ดํ๋ก lines
๋ ์ฌ์ฉํ ์ ์๋ค.
if !header {
// note: `skip` takes ownership of the receiver `self`, which moves `lines`
}
์ฐธ๊ณ ๋ก ์ด๊ฒ๋ ์๋๋ค. ํ์ ์๋ฌ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
let mut given_lines = src.lines();
let lines;
if header {
lines = given_lines;
} else {
lines = given_lines.skip(1);
// Type mismatch [E0308] expected `Lines<impl BufRead+Sized>`,
// but found `Skip<Lines<impl BufRead+Sized>>`
}
๋ฌผ๋ก ํด๊ฒฐํ๋ ๋ฐ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋ช
๋ฐฑํ next()
์ด๋ค. ํ ์ค๋ง ์คํตํ๋ฉด ๋๋๊น. ํ์ง๋ง ์ฌ๋ฌ ๊ฐ๋ฅผ ์คํตํ ๋ ์ด๋ป๊ฒ ํด์ผํ ๊น?
3. advance_by()
advance_by()
๋ ํ์ฌ ์ํฉ์ ๊ฐ์ฅ ๋ง๋ ๋ฉ์๋์ด๋ค.
๊ธฐ์กด์ iterator๋ฅผ ์์ ํ๊ณ move๊ฐ ์ผ์ด๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
lines.advance_by(3);
๊ทผ๋ฐ ๋จ์ ์ ์์ฑ ์์ ์ธ 2023.9 ๊ธฐ์ค์ผ๋ก ์์ง Nightly์๋ง ์กด์ฌํ๋ค๋ ๊ฒ์ด๋ค.
๋ฐ๋ผ์ ์ง์ ํจ์๋ฅผ ๋ง๋ค์ด์ ์งํ์ด ํ์ํ๋ค.
fn advance_by(iter: &mut impl Iterator, n: usize) -> Result<()> {
for _ in 0..n {
iter.next();
}
Ok(())
}
// ...
fn parse_csv_document(src: impl BufRead, header: bool) -> Result<Vec<Vec<String>>> {
// ...
if !header {
advance_by(&mut lines, 1)?;
}
// ...
}
๋จ์ํ์ง๋ง loop์ ๋๋ ค next()
๋ฅผ ์คํํด์ฃผ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ด๋ ๊ฒ ํ๋ฉด next()
๋ฅผ ๋์ ์ผ๋ก ์ฃผ์ด์ง ํ์๋งํผ ์คํํ์ฌ skip(N)
์ ๋ฐ๋ผํ ์ ์๋ค.
๋ฌผ๋ก immutableํ๊ฒ ์คํํ๊ณ ์ถ๋ค๋ฉด skip๊ณผ map์ ์ ์กฐํฉํด์ฃผ๋ฉด ๋๊ฒ ๋ค.
Referernce
Last updated
Was this helpful?