gpt4 book ai didi

rust - 如何将 Peekable 迭代器转换回原始迭代器?

转载 作者:行者123 更新时间:2023-11-29 08:12:29 28 4
gpt4 key购买 nike

我想实现一个在字符串开头跳过 !!^num 的算法:

fn extract_common_part(a: &str) -> Option<&str> {
let mut it = a.chars();
if it.next() != Some('!') {
return None;
}
let mut jt = it.clone().peekable();

if jt.peek() == Some(&'^') {
it.next();
jt.next();
while jt.peek().map_or(false, |v| !v.is_whitespace()) {
it.next();
jt.next();
}
it.next();
}
Some(it.as_str())
}

fn main() {
assert_eq!(extract_common_part("!^4324 1234"), Some("1234"));
assert_eq!(extract_common_part("!1234"), Some("1234"));
}

playground

这行得通,但我找不到从 Peekable 返回到 Chars 的方法,所以我必须推进 it jt 迭代器。这会导致重复代码。

如何从 Peekable 迭代器返回到相应的 Chars 迭代器,或者是否有更简单的方法来实现该算法?

最佳答案

简而言之,你不能。一般的答案是使用类似 Iterator::by_ref 的东西避免使用 Chars 迭代器:

fn extract_common_part(a: &str) -> Option<&str> {
let mut it = a.chars();
if it.next() != Some('!') {
return None;
}

{
let mut jt = it.by_ref().peekable();

if jt.peek() == Some(&'^') {
jt.next();
while jt.peek().map_or(false, |v| !v.is_whitespace()) {
jt.next();
}
}
}

Some(it.as_str())
}

问题是,当您调用 peek 并且它失败时,底层迭代器已经被推进。获取字符串的其余部分将丢失测试为 false 的字符,返回 234

但是,Itertools 有 peeking_take_whiletake_while_ref ,两者都应该可以解决问题。

extern crate itertools;

use itertools::Itertools;

fn extract_common_part(a: &str) -> Option<&str> {
let mut it = a.chars();
if it.next() != Some('!') {
return None;
}

if it.peeking_take_while(|&c| c == '^').next() == Some('^') {
for _ in it.peeking_take_while(|v| !v.is_whitespace()) {}
for _ in it.peeking_take_while(|v| v.is_whitespace()) {}
}

Some(it.as_str())
}

其他选项包括:

  • 使用类似 strcursor 的 crate 这是为这种对字符串的增量推进而设计的。
  • 直接对常规字符串进行解析,希望优化器消除冗余边界检查。
  • 使用正则表达式或其他解析库

关于rust - 如何将 Peekable 迭代器转换回原始迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43302639/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com