Rayon find_any 和 return 找到的物品的价值
Rayon find_any, and return the found item's value
假设我有一个带有签名
的函数f
fn f(a: u8) -> Result<bool, SomeError> {}
现在我有一个 Vec<u8>
,我想找出这个 Vec 中是否有任何元素,其 f
的值是 Ok(b)
,在这种情况下,return 值 b
(并停止为 Vec 的其余部分计算 f
)。我希望有一个带有签名的函数
fn my_function(v: Vec<u8>) -> Option<bool> {}
这是我的第一个实现:
fn my_function(v: Vec<u8>) -> Option<bool> {
let found = v.par_iter().find_any(|a| f(a).is_ok());
match found {
Some(a) => Some(f(a).unwrap()),
None => None
}
}
但我最后做了一个无用的 f
计算。我怎样才能重构代码来避免这个额外的 f
调用?
Rayon 的 map
、filter
、reduce
将不起作用,因为它们会遍历整个 Vec,我想避免这种情况。
Rayon's .flat_map(…)
method will apply f
to each element, treat each return value as an iterator, and flatten all of those results into a single new iterator. Result
s can be used as iterables of one (if Ok
) or zero (if Err
) elements,因此这具有展开 Ok
结果并丢弃 Err
的效果。然后,您可以应用 .find_any(|_| true)
来获取第一个可用的结果值,而无需再次调用 f(…)
.
use rayon::prelude::*;
fn my_function(v: Vec<u8>) -> Option<bool> {
v.par_iter().flat_map(|x| f(*x)).find_any(|_| true)
}
fn f(a: u8) -> Result<bool, SomeError> {
if a == 42 {
Ok(true)
} else {
Err(SomeError {})
}
}
fn main() {
println!("{:?}", my_function(vec![0, 1, 2, 42, 3, 42, 0]));
}
#[derive(Debug)]
struct SomeError {}
impl std::error::Error for SomeError {}
impl std::fmt::Display for SomeError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
Playground Output
Some(true)
假设我有一个带有签名
的函数f
fn f(a: u8) -> Result<bool, SomeError> {}
现在我有一个 Vec<u8>
,我想找出这个 Vec 中是否有任何元素,其 f
的值是 Ok(b)
,在这种情况下,return 值 b
(并停止为 Vec 的其余部分计算 f
)。我希望有一个带有签名的函数
fn my_function(v: Vec<u8>) -> Option<bool> {}
这是我的第一个实现:
fn my_function(v: Vec<u8>) -> Option<bool> {
let found = v.par_iter().find_any(|a| f(a).is_ok());
match found {
Some(a) => Some(f(a).unwrap()),
None => None
}
}
但我最后做了一个无用的 f
计算。我怎样才能重构代码来避免这个额外的 f
调用?
Rayon 的 map
、filter
、reduce
将不起作用,因为它们会遍历整个 Vec,我想避免这种情况。
Rayon's .flat_map(…)
method will apply f
to each element, treat each return value as an iterator, and flatten all of those results into a single new iterator. Result
s can be used as iterables of one (if Ok
) or zero (if Err
) elements,因此这具有展开 Ok
结果并丢弃 Err
的效果。然后,您可以应用 .find_any(|_| true)
来获取第一个可用的结果值,而无需再次调用 f(…)
.
use rayon::prelude::*;
fn my_function(v: Vec<u8>) -> Option<bool> {
v.par_iter().flat_map(|x| f(*x)).find_any(|_| true)
}
fn f(a: u8) -> Result<bool, SomeError> {
if a == 42 {
Ok(true)
} else {
Err(SomeError {})
}
}
fn main() {
println!("{:?}", my_function(vec![0, 1, 2, 42, 3, 42, 0]));
}
#[derive(Debug)]
struct SomeError {}
impl std::error::Error for SomeError {}
impl std::fmt::Display for SomeError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
Playground Output
Some(true)