Skip to content

Commit 662aab1

Browse files
New GroupingMap::minmax[_by[_key]]_in
1 parent 836993a commit 662aab1

File tree

1 file changed

+60
-26
lines changed

1 file changed

+60
-26
lines changed

src/grouping_map.rs

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ where
446446
where
447447
V: Ord,
448448
{
449-
self.minmax_by(|_, v1, v2| V::cmp(v1, v2))
449+
self.minmax_in(HashMap::new())
450450
}
451451

452452
/// Groups elements from the `GroupingMap` source by key and find the maximum and minimum of
@@ -472,32 +472,11 @@ where
472472
/// assert_eq!(lookup[&2], OneElement(5));
473473
/// assert_eq!(lookup.len(), 3);
474474
/// ```
475-
pub fn minmax_by<F>(self, mut compare: F) -> HashMap<K, MinMaxResult<V>>
475+
pub fn minmax_by<F>(self, compare: F) -> HashMap<K, MinMaxResult<V>>
476476
where
477477
F: FnMut(&K, &V, &V) -> Ordering,
478478
{
479-
self.aggregate(|acc, key, val| {
480-
Some(match acc {
481-
Some(MinMaxResult::OneElement(e)) => {
482-
if compare(key, &val, &e) == Ordering::Less {
483-
MinMaxResult::MinMax(val, e)
484-
} else {
485-
MinMaxResult::MinMax(e, val)
486-
}
487-
}
488-
Some(MinMaxResult::MinMax(min, max)) => {
489-
if compare(key, &val, &min) == Ordering::Less {
490-
MinMaxResult::MinMax(val, max)
491-
} else if compare(key, &val, &max) != Ordering::Less {
492-
MinMaxResult::MinMax(min, val)
493-
} else {
494-
MinMaxResult::MinMax(min, max)
495-
}
496-
}
497-
None => MinMaxResult::OneElement(val),
498-
Some(MinMaxResult::NoElements) => unreachable!(),
499-
})
500-
})
479+
self.minmax_by_in(compare, HashMap::new())
501480
}
502481

503482
/// Groups elements from the `GroupingMap` source by key and find the elements of each group
@@ -523,12 +502,12 @@ where
523502
/// assert_eq!(lookup[&2], OneElement(5));
524503
/// assert_eq!(lookup.len(), 3);
525504
/// ```
526-
pub fn minmax_by_key<F, CK>(self, mut f: F) -> HashMap<K, MinMaxResult<V>>
505+
pub fn minmax_by_key<F, CK>(self, f: F) -> HashMap<K, MinMaxResult<V>>
527506
where
528507
F: FnMut(&K, &V) -> CK,
529508
CK: Ord,
530509
{
531-
self.minmax_by(|key, v1, v2| f(key, v1).cmp(&f(key, v2)))
510+
self.minmax_by_key_in(f, HashMap::new())
532511
}
533512

534513
/// Groups elements from the `GroupingMap` source by key and sums them.
@@ -742,4 +721,59 @@ where
742721
{
743722
self.min_by_in(|key, v1, v2| f(key, v1).cmp(&f(key, v2)), map)
744723
}
724+
725+
/// Apply [`minmax`](Self::minmax) with a provided empty map
726+
/// (`BTreeMap` or `HashMap` with any hasher).
727+
pub fn minmax_in<M>(self, map: M) -> M
728+
where
729+
V: Ord,
730+
M: Map<Key = K, Value = MinMaxResult<V>>,
731+
{
732+
self.minmax_by_in(|_, v1, v2| V::cmp(v1, v2), map)
733+
}
734+
735+
/// Apply [`minmax_by`](Self::minmax_by) with a provided empty map
736+
/// (`BTreeMap` or `HashMap` with any hasher).
737+
pub fn minmax_by_in<F, M>(self, mut compare: F, map: M) -> M
738+
where
739+
F: FnMut(&K, &V, &V) -> Ordering,
740+
M: Map<Key = K, Value = MinMaxResult<V>>,
741+
{
742+
self.aggregate_in(
743+
|acc, key, val| {
744+
Some(match acc {
745+
Some(MinMaxResult::OneElement(e)) => {
746+
if compare(key, &val, &e) == Ordering::Less {
747+
MinMaxResult::MinMax(val, e)
748+
} else {
749+
MinMaxResult::MinMax(e, val)
750+
}
751+
}
752+
Some(MinMaxResult::MinMax(min, max)) => {
753+
if compare(key, &val, &min) == Ordering::Less {
754+
MinMaxResult::MinMax(val, max)
755+
} else if compare(key, &val, &max) != Ordering::Less {
756+
MinMaxResult::MinMax(min, val)
757+
} else {
758+
MinMaxResult::MinMax(min, max)
759+
}
760+
}
761+
None => MinMaxResult::OneElement(val),
762+
Some(MinMaxResult::NoElements) => unreachable!(),
763+
})
764+
},
765+
map,
766+
)
767+
}
768+
769+
/// Apply [`minmax_by_key`](Self::minmax_by_key) with a provided empty map
770+
/// (`BTreeMap` or `HashMap` with any hasher).
771+
pub fn minmax_by_key_in<F, CK, M>(self, mut f: F, map: M) -> M
772+
where
773+
F: FnMut(&K, &V) -> CK,
774+
CK: Ord,
775+
M: Map<Key = K, Value = MinMaxResult<V>>,
776+
{
777+
self.minmax_by_in(|key, v1, v2| f(key, v1).cmp(&f(key, v2)), map)
778+
}
745779
}

0 commit comments

Comments
 (0)