如何在 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()returnIterators,不是切片。您可以使用 as_bytes(),这会给您一个 &[u8]。但是,你不能直接从&str中得到一个&[char],因为只有字节本身,而char必须通过查看每个字节组成多少字节来创建一。你必须做这样的事情:

text.chars()
    .collect::<Vec<char>>()
    .chunks(n)
    .map(|c| c.iter().collect::<String>())
    .collect::<Vec<String>>()
    .join(" ");

但是,我不推荐这样做,因为它必须在整个过程中为 Vecs 和 Strings 分配大量临时存储空间。相反,你可以做这样的事情,只需要分配来创建最终的 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 = "&#8204;&#8203;&#8204;&#8203;&#8204;&#8203;&#8203;&#8204;&#8203;&#8204;".as_bytes()
        .chunks(7)
        .map(str::from_utf8)
        .collect::<Result<Vec<&str>, _>>()
        .unwrap();
        
    println!("{:?}", subs);
}

// >> ["&#8204;", "&#8203;", "&#8204;", "&#8203;", "&#8204;", "&#8203;", "&#8203;", "&#8204;", "&#8203;", "&#8204;"]