From 0ab8f78834f78eaafc9d405d5e8fe8a4195fea33 Mon Sep 17 00:00:00 2001 From: yjhmelody <465402634@qq.com> Date: Tue, 29 Oct 2019 20:41:10 +0800 Subject: [PATCH 1/3] add max_by_key --- src/stream/stream/max_by_key.rs | 60 +++++++++++++++++++++++++++++++++ src/stream/stream/mod.rs | 45 +++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/stream/stream/max_by_key.rs diff --git a/src/stream/stream/max_by_key.rs b/src/stream/stream/max_by_key.rs new file mode 100644 index 000000000..b3fb65bf4 --- /dev/null +++ b/src/stream/stream/max_by_key.rs @@ -0,0 +1,60 @@ +use std::cmp::Ordering; +use std::pin::Pin; + +use pin_project_lite::pin_project; + +use crate::future::Future; +use crate::stream::Stream; +use crate::task::{Context, Poll}; + +pin_project! { + #[doc(hidden)] + #[allow(missing_debug_implementations)] + pub struct MaxByKeyFuture { + #[pin] + stream: S, + max: Option, + key_by: K, + } +} + +impl MaxByKeyFuture { + pub(super) fn new(stream: S, key_by: K) -> Self { + Self { + stream, + max: None, + key_by, + } + } +} + +impl Future for MaxByKeyFuture +where + S: Stream, + K: FnMut(&S::Item) -> S::Item, + S::Item: Ord, +{ + type Output = Option; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.project(); + let next = futures_core::ready!(this.stream.poll_next(cx)); + + match next { + Some(new) => { + let new = (this.key_by)(&new); + cx.waker().wake_by_ref(); + match this.max.take() { + None => *this.max = Some(new), + + Some(old) => match new.cmp(&old) { + Ordering::Greater => *this.max = Some(new), + _ => *this.max = Some(old), + }, + } + Poll::Pending + } + None => Poll::Ready(this.max.take()), + } + } +} diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index e46ca9e5c..e1d708c04 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -42,7 +42,11 @@ mod le; mod lt; mod map; mod max_by; +<<<<<<< HEAD mod min; +======= +mod max_by_key; +>>>>>>> add max_by_key mod min_by; mod min_by_key; mod ne; @@ -76,7 +80,11 @@ use last::LastFuture; use le::LeFuture; use lt::LtFuture; use max_by::MaxByFuture; +<<<<<<< HEAD use min::MinFuture; +======= +use max_by_key::MaxByKeyFuture; +>>>>>>> add max_by_key use min_by::MinByFuture; use min_by_key::MinByKeyFuture; use ne::NeFuture; @@ -729,6 +737,43 @@ extension_trait! { MinByKeyFuture::new(self, key_by) } + #[doc = r#" + Returns the element that gives the maximum value with respect to the + specified key function. If several elements are equally maximum, + the first element is returned. If the stream is empty, `None` is returned. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use std::collections::VecDeque; + + use async_std::prelude::*; + + let s: VecDeque = vec![-1, -2, -3].into_iter().collect(); + + let max = s.clone().max_by_key(|x| x.abs()).await; + assert_eq!(max, Some(3)); + + let max = VecDeque::::new().max_by_key(|x| x.abs()).await; + assert_eq!(max, None); + # + # }) } + ``` + "#] + fn max_by_key( + self, + key_by: K, + ) -> impl Future> [MaxByKeyFuture] + where + Self: Sized, + Self::Item: Ord, + K: FnMut(&Self::Item) -> Self::Item, + { + MaxByKeyFuture::new(self, key_by) + } + #[doc = r#" Returns the element that gives the minimum value with respect to the specified comparison function. If several elements are equally minimum, From 59e8cd30fc67c50cbef8a8914e2e88b6f8257d33 Mon Sep 17 00:00:00 2001 From: yjhmelody <465402634@qq.com> Date: Sat, 2 Nov 2019 11:35:23 +0800 Subject: [PATCH 2/3] fix conflict --- src/stream/stream/mod.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index e1d708c04..fbbc46691 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -42,11 +42,8 @@ mod le; mod lt; mod map; mod max_by; -<<<<<<< HEAD mod min; -======= mod max_by_key; ->>>>>>> add max_by_key mod min_by; mod min_by_key; mod ne; @@ -80,11 +77,8 @@ use last::LastFuture; use le::LeFuture; use lt::LtFuture; use max_by::MaxByFuture; -<<<<<<< HEAD use min::MinFuture; -======= use max_by_key::MaxByKeyFuture; ->>>>>>> add max_by_key use min_by::MinByFuture; use min_by_key::MinByKeyFuture; use ne::NeFuture; From 1a0a46f6bae56d03da903f479c2e0dd7c680c625 Mon Sep 17 00:00:00 2001 From: yjhmelody <465402634@qq.com> Date: Sat, 2 Nov 2019 11:41:48 +0800 Subject: [PATCH 3/3] fmt code --- src/stream/stream/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index fbbc46691..c099dc181 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -42,8 +42,8 @@ mod le; mod lt; mod map; mod max_by; -mod min; mod max_by_key; +mod min; mod min_by; mod min_by_key; mod ne; @@ -77,8 +77,8 @@ use last::LastFuture; use le::LeFuture; use lt::LtFuture; use max_by::MaxByFuture; -use min::MinFuture; use max_by_key::MaxByKeyFuture; +use min::MinFuture; use min_by::MinByFuture; use min_by_key::MinByKeyFuture; use ne::NeFuture;