由于字符串支持迭代但不支持索引,我想将字符串转换为字符列表。 我有"abc"
,我想要['a','b','c']
。
只要我可以索引它,它就可以是任何类型。 一个Vec<char>
或[char; 3]
都可以,其他想法也很有趣!
速度越快越好,因为我在处理非常长的字符串。 在假定字符串为ASCII时更有效的版本也很酷。
由于字符串支持迭代但不支持索引,我想将字符串转换为字符列表。 我有"abc"
,我想要['a','b','c']
。
只要我可以索引它,它就可以是任何类型。 一个Vec<char>
或[char; 3]
都可以,其他想法也很有趣!
速度越快越好,因为我在处理非常长的字符串。 在假定字符串为ASCII时更有效的版本也很酷。
使用String
或str
上的chars
方法:
fn main() {
let s = "Hello world!";
let char_vec: Vec<char> = s.chars().collect();
for c in char_vec {
println!("{}", c);
}
}
这里有一个实时示例
我已经得出了这个解决方案:
let chars: Vec<char> = input.chars().collect();
在评论中有人建议使用.split("")
,但似乎它的实现方式对于这种情况来说很烦人:
println!("{:?}", "abc".split("").collect::<Vec<&str>>());
返回 ["", "a", "b", "c", ""]
split("")
返回的Vec<&str>
,但是你不想要开头和结尾的空字符串,可以使用split_terminator("").skip(1)
。 - trent假设你正在尝试解决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
方法返回最后一个值,其中包含累积结果和最后一个字符。此时,您可以检查最后一个字符是否与第一个字符相同,如果需要,则更新结果。