如何将字符串转换为字符列表?

57

由于字符串支持迭代但不支持索引,我想将字符串转换为字符列表。 我有"abc",我想要['a','b','c']

只要我可以索引它,它就可以是任何类型。 一个Vec<char>[char; 3]都可以,其他想法也很有趣!

速度越快越好,因为我在处理非常长的字符串。 在假定字符串为ASCII时更有效的版本也很酷。


1
我想知道为什么你需要对其进行索引?也许这是一个XY问题。标准库中有很多工具可以处理字符串,我看不到查找字符串的随机访问的任何理由。 - Boiethios
我正在工作,公司阻止聊天。我提出这个问题,因为也许您的问题可以在不索引字符的情况下解决。 - Boiethios
3个回答

88

使用Stringstr上的chars方法:

fn main() {
    let s = "Hello world!";
    let char_vec: Vec<char> = s.chars().collect();
    for c in char_vec {
        println!("{}", c);
    }
}

这里有一个实时示例


4
您可以在字符串上调用chars()函数,而不需要使用to_string()。 - Sarien

18

我已经得出了这个解决方案:

let chars: Vec<char> = input.chars().collect();

在评论中有人建议使用.split(""),但似乎它的实现方式对于这种情况来说很烦人:

println!("{:?}", "abc".split("").collect::<Vec<&str>>());

返回 ["", "a", "b", "c", ""]


5
如果你想要一个类似于split("")返回的Vec<&str>,但是你不想要开头和结尾的空字符串,可以使用split_terminator("").skip(1) - trent

3

假设你正在尝试解决Advent of Code的第一天,我认为你需要比较两个连续的字符,并根据这些字符是否相同来更新累加器。你可以使用chars上的fold函数来完成此操作,而无需使用索引。以下是一个示例(未经测试):

fn example(s: &str) -> u32 {
    let mut i = s.chars()
        .map(|c| c.to_digit(10).expect("Invalid input: Non-digit found!"));
    if let Some(first) = i.next() {
        let (tot, last) = i.fold((0, first), |acc, x| {
            let (tot, prev) = acc;
            if prev == x {
                (tot + prev, x)
            } else {
                (tot, x)
            }
        });
        if last == first {
            tot + last
        } else {
            tot
        }
    } else {
        0
    }
}
fold 迭代器方法允许您在每个步骤更新值的情况下遍历值的所有迭代项。在这里,该值是一个元组,其中包含累积结果和前一个数字的值。我们使用一些初始结果和第一个字符的值进行初始化。然后在每个步骤中,我们将当前字符与从当前值中获取的上一个字符进行比较,根据比较结果更新累积结果,并返回一个新值,其中包含更新的累加器和当前字符。 fold 方法返回最后一个值,其中包含累积结果和最后一个字符。此时,您可以检查最后一个字符是否与第一个字符相同,如果需要,则更新结果。

有趣的想法。对于第一个问题的第一部分,我有类似的想法,但认为以这种方式不同地处理开头和结尾有点混乱。在第二部分中,偏移量是不同的,这变得不可行。 - Sarien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接