如何在 Rust 中将字符串拆分为块以插入空格
How to split string into chunks in Rust to insert spaces
我正在尝试学习 Rust。我最近遇到的一个问题如下:
给定一个 String
,正好是 n 的倍数,我想将字符串拆分为大小为 n 的块,并在这些块之间插入一个 space,然后收集回一个字符串。
我 运行 遇到的问题是 chars()
方法 returns 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()
returnIterator
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
s 和 String
s 分配大量临时存储空间。相反,你可以做这样的事情,只需要分配来创建最终的 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 迭代器要么只是字符,要么是 space 然后是字符。
因此,如果您想从一个字符列表中创建一个字符串,您可以使用 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);
}
// >> ["‌", "​", "‌", "​", "‌", "​", "​", "‌", "​", "‌"]
我正在尝试学习 Rust。我最近遇到的一个问题如下:
给定一个 String
,正好是 n 的倍数,我想将字符串拆分为大小为 n 的块,并在这些块之间插入一个 space,然后收集回一个字符串。
我 运行 遇到的问题是 chars()
方法 returns 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()
returnIterator
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
s 和 String
s 分配大量临时存储空间。相反,你可以做这样的事情,只需要分配来创建最终的 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 迭代器要么只是字符,要么是 space 然后是字符。
因此,如果您想从一个字符列表中创建一个字符串,您可以使用 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);
}
// >> ["‌", "​", "‌", "​", "‌", "​", "​", "‌", "​", "‌"]