如何在 Rust 中迭代 str 或 String 的前缀和后缀?
How to iterate prefixes and suffixes of str or String in rust?
我有一个字符串:“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表示字符串,索引都是byte offsets
- 切片代码点的一部分没有任何意义并且会产生垃圾数据。 Rust 选择恐慌:
#[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 有:
-
一个解决方案
警告:此代码在代码点级别工作,并且忽略了字素簇。
从最短到最长:
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()
另请参阅:
我有一个字符串:“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表示字符串,索引都是byte offsets
- 切片代码点的一部分没有任何意义并且会产生垃圾数据。 Rust 选择恐慌:
#[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 有:
一个解决方案
警告:此代码在代码点级别工作,并且忽略了字素簇。
从最短到最长:
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()
另请参阅: