`BTreeMap::append_with` that allows custom value merges
@asder8215 is already working on this.
Since Feb 1, 2026.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I don't have much more to add than what https://internals.rust-lang.org/t/btreemap-methods-insert-append-to-combine-values-instead-of-overwriting/21353 describes. In brief, it would be great to have a version of BTreeMap::append that would allow to decide what to do when both maps contain a key.
The API could look like this:
pub fn append_with(&mut self, other: &mut BTreeMap<K, V, A>, conflict: impl FnMut(&K, &mut V, V));
with the first argument providing a mutable reference to the value in Self, while the 2nd argument is an owned value from other that's to be merged in. The closure might also want to provide the key (or not) as the 0th argument to the closure.
Functionally this function should probably be equivalent to:
pub fn append_with(into: &mut BTreeMap<K, V, A>, other: &mut BTreeMap<K, V, A>, conflict: impl FnMut(&K, &mut V, V)) {
for (key, value) in std::mem::take(other) {
match into.entry(key) {
Vacant(ve) => ve.insert(value),
Occupied(oe) => conflict(oe.key(), oe.get_mut(), value),
}
}
}
except that it would be implemented to be roughly O(n) instead of this O(n log n) implementation.
Other ideas: the conflict function could be made to return a core::ops::ControlFlow to control whether the appending should continue or terminate.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.