我有一个类似" aaaabbbccccc"的字符串。我想在字符串的chars
迭代器上创建一个适配器,它产生相同字符的计数。输出(count
)必须是连续相同字符的数量。例如:
let s = "aaaabbbccccc"
for count in s.chars().MAGIC() {
println!("{}", count)
}
// prints: 4, 3, 5
更新:这几乎可行:过去不考虑这封信:
let s = "aaaabbbcccccdd".to_string();
let mut tt = (s.chars().nth(0).unwrap(), 0);
for a in s.chars().filter_map(|x| {
if x != tt.0 {
tt.0 = x;
let tt_temp = tt.1;
tt.1 = 1;
Some(tt_temp)
} else {
tt.1 += 1;
None
}
}) {
println!("{:?}", a);
}
答案 0 :(得分:3)
使用itertools' .coalesce()
,你可以这样做:
// Map each char to an initial count of 1, then merge counts for identical chars
.map(|c| (c, 1)).coalesce(|(c, n), (d, m)|
if c == d { Ok((c, n + m)) } else { Err(((c, n), (d, m))) })
答案 1 :(得分:2)
仅使用标准库:
use std::iter::Peekable;
struct SequentialCount<I>
where I: Iterator
{
iter: Peekable<I>,
}
impl<I> SequentialCount<I>
where I: Iterator
{
fn new(iter: I) -> Self {
SequentialCount { iter: iter.peekable() }
}
}
impl<I> Iterator for SequentialCount<I>
where I: Iterator,
I::Item: Eq
{
type Item = (I::Item, usize);
fn next(&mut self) -> Option<Self::Item> {
// Check the next value in the inner iterator
match self.iter.next() {
// There is a value, so keep it
Some(head) => {
// We've seen one value so far
let mut count = 1;
// Check to see what the next value is without
// actually advancing the inner iterator
while self.iter.peek() == Some(&head) {
// It's the same value, so go ahead and consume it
self.iter.next();
count += 1;
}
// The next element doesn't match the current value
// complete this iteration
Some((head, count))
}
// The inner iterator is complete, so we are also complete
None => None,
}
}
}
fn main() {
let s = "aaaabbbccccc";
for (char, count) in SequentialCount::new(s.chars()) {
println!("{} occurs {} times", char, count)
}
}
当然,您可以通常的工作来创建扩展特征以在迭代器上添加方法:
trait SequentialCountAdapter: Iterator {
fn sequential_count(self) -> SequentialCount<Self>
where Self: Sized
{
SequentialCount::new(self)
}
}
impl<I> SequentialCountAdapter for I where I: Iterator {}