[英]How to split string into chunks in Rust to insert spaces
我正在尝试学习 Rust。 我最近遇到的一个问题如下:给定一个String
,它恰好是 n 的某个倍数,我想将字符串拆分为大小为 n 的块,并在这些块之间插入一个空格,然后收集回一个单个字符串。
我遇到的问题是chars()
方法返回Chars
结构,由于某种原因它没有实现SliceConcatExt
特征,因此无法调用chunks()
。
此外,一旦我成功创建了一个 Chunks 结构(通过调用.bytes()
代替),我不确定如何调用.join(' ')
因为元素现在是字节切片的Chunks
......
必须有一种优雅的方式来做到这一点,我错过了。
例如,这是一个说明情况的输入/输出:
given: whatupmyname, 4
output: what upmy name
这是我写得很糟糕的尝试:
let n = 4;
let text = "whatupmyname".into_string();
text.chars()
// compiler error on chunks() call
.chunks(n)
.collect::<Vec<String>>()
.join(' ')
这里的问题是chars()
和bytes()
返回Iterator
s,而不是切片。 你可以使用as_bytes()
,它会给你一个&[u8]
。 但是,您不能直接从&str
中获取&[char]
,因为只存在字节本身,并且char
必须通过查看并查看每个字节组成的字节数来创建。 你必须做这样的事情:
text.chars()
.collect::<Vec<char>>()
.chunks(n)
.map(|c| c.iter().collect::<String>())
.collect::<Vec<String>>()
.join(" ");
但是,我不建议这样做,因为它必须在此过程中为Vec
和String
分配大量临时存储空间。 相反,你可以做这样的事情,它只需要分配来创建最终的String
。
text.chars()
.enumerate()
.flat_map(|(i, c)| {
if i != 0 && i % n == 0 {
Some(' ')
} else {
None
}
.into_iter()
.chain(std::iter::once(c))
})
.collect::<String>()
在最后一次收集之前,它一直作为迭代器,通过 flat_mapping 使用一个迭代器,该迭代器要么只是字符,要么是空格,然后是字符。
所以如果你想从一个字符列表中创建一个字符串,你可以使用fold 。
像这样的东西:
text.chars
.enumerate()
.fold(String::new(), |acc, (i, c)| {
if i != 0 && i == n {
format!("{} {}", acc, c)
} else {
format!("{}{}", acc, c)
}
})
如果要拆分的数据大小是固定的,则:
use std::str;
fn main() {
let subs = "‌​‌​‌​​‌​‌".as_bytes()
.chunks(7)
.map(str::from_utf8)
.collect::<Result<Vec<&str>, _>>()
.unwrap();
println!("{:?}", subs);
}
// >> ["‌", "​", "‌", "​", "‌", "​", "​", "‌", "​", "‌"]
这样一个简单的任务可以用一个while
循环来解决:
fn main() {
let n = 4;
let text = "whatupmyname";
let mut it = text.chars().enumerate();
let mut rslt = String::from("");
while let Some((i, c)) = it.next() {
rslt.push(c);
if (i + 1) % n == 0 {
rslt.push(' ');
}
}
println!("{}", rslt);
}
为了完整起见,这里是 Chayim-Friedman 风格的循环(见评论) :
…
for (i, c) in text.chars().enumerate() {
rslt.push(c);
if (i + 1) % n == 0 {
rslt.push(' ');
}
}
…
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.