浏览代码

Implemented 'find_map_any', 'find_map_first' and 'find_map_last' operation

master
Bergmann89 5 年前
父节点
当前提交
ea02795fa7
共有 3 个文件被更改,包括 138 次插入9 次删除
  1. +94
    -1
      asparit/src/core/iterator.rs
  2. +44
    -7
      asparit/src/inner/find.rs
  3. +0
    -1
      asparit/src/inner/mod.rs

+ 94
- 1
asparit/src/core/iterator.rs 查看文件

@@ -15,7 +15,7 @@ use crate::{
count::Count,
filter::Filter,
filter_map::FilterMap,
find::{Find, FindMatch},
find::{Find, FindMap, FindMatch},
flatten::{FlatMapIter, FlattenIter},
fold::{Fold, FoldWith},
for_each::ForEach,
@@ -1359,6 +1359,99 @@ pub trait ParallelIterator<'a>: Sized + Send {
Find::new(self, operation, FindMatch::Last)
}

/// Applies the given operation to the items in the parallel iterator
/// and returns **any** non-None result of the map operation.
///
/// Once a non-None value is produced from the map operation, we will
/// attempt to stop processing the rest of the items in the iterator
/// as soon as possible.
///
/// Note that this method only returns **some** item in the parallel
/// iterator that is not None from the map operation. The item returned
/// may not be the **first** non-None value produced in the parallel
/// sequence, since the entire sequence is mapped over in parallel.
///
/// # Examples
///
/// ```
/// use rayon::prelude::*;
///
/// let c = ["lol", "NaN", "5", "5"];
///
/// let found_number = c.par_iter().find_map_any(|s| s.parse().ok());
///
/// assert_eq!(found_number, Some(5));
/// ```
fn find_map_any<O, T>(self, operation: O) -> FindMap<Self, O>
where
O: Fn(Self::Item) -> Option<T> + Clone + Send + 'a,
T: Send,
{
FindMap::new(self, operation, FindMatch::Any)
}

/// Applies the given operation to the items in the parallel iterator and
/// returns the sequentially **first** non-None result of the map operation.
///
/// Once a non-None value is produced from the map operation, all attempts
/// to the right of the match will be stopped, while attempts to the left
/// must continue in case an earlier match is found.
///
/// Note that not all parallel iterators have a useful order, much like
/// sequential `HashMap` iteration, so "first" may be nebulous. If you
/// just want the first non-None value discovered anywhere in the iterator,
/// `find_map_any` is a better choice.
///
/// # Examples
///
/// ```
/// use rayon::prelude::*;
///
/// let c = ["lol", "NaN", "2", "5"];
///
/// let first_number = c.par_iter().find_map_first(|s| s.parse().ok());
///
/// assert_eq!(first_number, Some(2));
/// ```
fn find_map_first<O, T>(self, operation: O) -> FindMap<Self, O>
where
O: Fn(Self::Item) -> Option<T> + Clone + Send + 'a,
T: Send,
{
FindMap::new(self, operation, FindMatch::First)
}

/// Applies the given operation to the items in the parallel iterator and
/// returns the sequentially **last** non-None result of the map operation.
///
/// Once a non-None value is produced from the map operation, all attempts
/// to the left of the match will be stopped, while attempts to the right
/// must continue in case a later match is found.
///
/// Note that not all parallel iterators have a useful order, much like
/// sequential `HashMap` iteration, so "first" may be nebulous. If you
/// just want the first non-None value discovered anywhere in the iterator,
/// `find_map_any` is a better choice.
///
/// # Examples
///
/// ```
/// use rayon::prelude::*;
///
/// let c = ["lol", "NaN", "2", "5"];
///
/// let last_number = c.par_iter().find_map_last(|s| s.parse().ok());
///
/// assert_eq!(last_number, Some(5));
/// ```
fn find_map_last<O, T>(self, operation: O) -> FindMap<Self, O>
where
O: Fn(Self::Item) -> Option<T> + Clone + Send + 'a,
T: Send,
{
FindMap::new(self, operation, FindMatch::Last)
}

/// Creates a fresh collection containing all the elements produced
/// by this parallel iterator.
///


+ 44
- 7
asparit/src/inner/find.rs 查看文件

@@ -5,6 +5,13 @@ use std::sync::{

use crate::{Consumer, Driver, Executor, Folder, ParallelIterator, Reducer};

#[derive(Copy, Clone, Eq, PartialEq)]
pub enum FindMatch {
Any,
First,
Last,
}

/* Find */

pub struct Find<X, O> {
@@ -13,13 +20,6 @@ pub struct Find<X, O> {
find_match: FindMatch,
}

#[derive(Copy, Clone, Eq, PartialEq)]
pub enum FindMatch {
Any,
First,
Last,
}

impl<X, O> Find<X, O> {
pub fn new(iterator: X, operation: O, find_match: FindMatch) -> Self {
Self {
@@ -51,6 +51,43 @@ where
}
}

/* FindMap */

pub struct FindMap<X, O> {
iterator: X,
operation: O,
find_match: FindMatch,
}

impl<X, O> FindMap<X, O> {
pub fn new(iterator: X, operation: O, find_match: FindMatch) -> Self {
Self {
iterator,
operation,
find_match,
}
}
}

impl<'a, X, O, T> Driver<'a, Option<T>> for FindMap<X, O>
where
X: ParallelIterator<'a>,
O: Fn(X::Item) -> Option<T> + Clone + Send + 'a,
T: Send + 'a,
{
fn exec_with<E>(self, executor: E) -> E::Result
where
E: Executor<'a, Option<T>>,
{
Find::new(
self.iterator.filter_map(self.operation),
|_: &T| true,
self.find_match,
)
.exec_with(executor)
}
}

/* FindConsumer */

struct FindConsumer<O> {


+ 0
- 1
asparit/src/inner/mod.rs 查看文件

@@ -67,7 +67,6 @@ mod tests {
Ok(())
},
)
// .find_any(|x| x.0 == 5)
.exec()
.await;



正在加载...
取消
保存