Skip to content

Commit

Permalink
New GroupingMap::aggregate_in
Browse files Browse the repository at this point in the history
Instead of `debug_assert!(map.is_empty());` we could alternatively `map.clear();`.
I have a preference for it but check it's empty is less surprising, right?!

Anyway, the documentation should state one or the other.
  • Loading branch information
Philippe-Cholet committed Mar 12, 2024
1 parent 3049c29 commit df7720d
Showing 1 changed file with 27 additions and 11 deletions.
38 changes: 27 additions & 11 deletions src/grouping_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::{
adaptors::map::{MapSpecialCase, MapSpecialCaseFn},
generic_containers::Map,
MinMaxResult,
};
use std::cmp::Ordering;
Expand Down Expand Up @@ -109,20 +110,11 @@ where
/// assert_eq!(lookup[&3], 7);
/// assert_eq!(lookup.len(), 3); // The final keys are only 0, 1 and 2
/// ```
pub fn aggregate<FO, R>(self, mut operation: FO) -> HashMap<K, R>
pub fn aggregate<FO, R>(self, operation: FO) -> HashMap<K, R>
where
FO: FnMut(Option<R>, &K, V) -> Option<R>,
{
let mut destination_map = HashMap::new();

self.iter.for_each(|(key, val)| {
let acc = destination_map.remove(&key);
if let Some(op_res) = operation(acc, &key, val) {
destination_map.insert(key, op_res);
}
});

destination_map
self.aggregate_in(operation, HashMap::new())
}

/// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
Expand Down Expand Up @@ -605,3 +597,27 @@ where
self.fold_first(|acc, _, val| acc * val)
}
}

impl<I, K, V> GroupingMap<I>
where
I: Iterator<Item = (K, V)>,
{
/// Apply [`aggregate`](Self::aggregate) with a provided empty map
/// (`BTreeMap` or `HashMap` with any hasher).
pub fn aggregate_in<FO, R, M>(self, mut operation: FO, mut map: M) -> M
where
FO: FnMut(Option<R>, &K, V) -> Option<R>,
M: Map<Key = K, Value = R>,
{
debug_assert!(map.is_empty());

self.iter.for_each(|(key, val)| {
let acc = map.remove(&key);
if let Some(op_res) = operation(acc, &key, val) {
map.insert(key, op_res);
}
});

map
}
}

0 comments on commit df7720d

Please sign in to comment.