Skip to content

Commit 2203cb6

Browse files
Map::aggregate
rust-itertools#901 (comment) SkiFire13 had the idea this could be optimized for vectors.
1 parent dc15e5c commit 2203cb6

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

src/generic_containers.rs

+19
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ pub trait Map {
1515
type Value;
1616
fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
1717
fn remove(&mut self, key: &Self::Key) -> Option<Self::Value>;
18+
fn aggregate<T, F>(&mut self, key: Self::Key, t: T, mut operation: F)
19+
where
20+
F: FnMut(Option<Self::Value>, &Self::Key, T) -> Option<Self::Value>,
21+
{
22+
let opt_value = self.remove(&key);
23+
if let Some(value) = operation(opt_value, &key, t) {
24+
self.insert(key, value);
25+
}
26+
}
1827
fn entry_or_default(&mut self, key: Self::Key) -> &mut Self::Value
1928
where
2029
Self::Value: Default;
@@ -81,6 +90,16 @@ where
8190
let index = self.iter().position(|(k, _)| k == key)?;
8291
Some(self.swap_remove(index).1)
8392
}
93+
fn aggregate<T, F>(&mut self, key: K, t: T, mut operation: F)
94+
where
95+
F: FnMut(Option<V>, &K, T) -> Option<V>,
96+
{
97+
let opt_value = Map::remove(self, &key);
98+
if let Some(value) = operation(opt_value, &key, t) {
99+
// The key was removed so a single push is enough to insert it back.
100+
self.push((key, value));
101+
}
102+
}
84103
fn entry_or_default(&mut self, key: K) -> &mut V
85104
where
86105
V: Default,

src/grouping_map.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,8 @@ where
144144
{
145145
let mut destination_map = self.map;
146146

147-
self.iter.for_each(|(key, val)| {
148-
let acc = destination_map.remove(&key);
149-
if let Some(op_res) = operation(acc, &key, val) {
150-
destination_map.insert(key, op_res);
151-
}
152-
});
147+
self.iter
148+
.for_each(|(key, val)| destination_map.aggregate(key, val, &mut operation));
153149

154150
destination_map
155151
}

0 commit comments

Comments
 (0)