如何在rust中迭代str或String的前缀和后缀?



我有一个字符串:"abcd"我想:

  • 从最短到最长迭代前缀:

    "、"a"ab","abc","abcd"

  • 从长到短迭代前缀:

    "abcd","abc","ab","a",">

  • 从最短到最长迭代其后缀:

    "、"d"cd","bcd","abcd"

  • 从长到短迭代其后缀:

    "abcd","bcd","cd","d",">

字符串比人们想象的要复杂得多

  • 为了符合人类的直觉,您通常希望将字符串视为0个或多个字形簇的序列。
  • 一个字素簇是一个由1个或多个Unicode码点组成的序列
  • 在utf8编码中,码点表示为1、2、3或4字节的序列
  • rust中的String和str都使用utf8来表示字符串,索引是字节偏移量
  • 切片代码点的一部分是没有意义的,并且会产生垃圾数据。Rust选择panic:
#[cfg(test)]
mod tests {
#[test]
#[should_panic(expected = "byte index 2 is not a char boundary; it is inside '\u{306}' (bytes 1..3) of `y̆`")]
fn bad_index() {
let y = "y̆";
&y[2..];
}
}
  • 在代码点级别rust有:

    • str.chars ()
    • str.char_indices ()
    • str.is_char_boundary ()
  • 进一步阅读:https://doc.rust-lang.org/book/ch08-02-strings.html

解决方案警告:这段代码在代码点级别上工作,并且是grapheme cluster无关的。

从最短到最长:

use core::iter;
pub fn prefixes(s: &str) -> impl Iterator<Item = &str> + DoubleEndedIterator {
s.char_indices()
.map(move |(pos, _)| &s[..pos])
.chain(iter::once(s))
}
pub fn suffixes(s: &str) -> impl Iterator<Item = &str> + DoubleEndedIterator {
s.char_indices()
.map(move |(pos, _)| &s[pos..])
.chain(iter::once(""))
.rev()
}

在反向:

prefixes(s).rev()
suffixes(s).rev()

测试参见:如何在rust中迭代vec或slice的前缀或后缀?

最新更新