-
Notifications
You must be signed in to change notification settings - Fork 318
Description
It is not the first time I'm missing a method to remove an arbitrary element from a set or map. This issue has been solved in the standard library for BTreeSet and BTreeMap with the recent introduction of the pop_first and pop_last methods, but there is no equivalent for HashMap/HashSet.
What I'm looking for is as simple as that:
/// Removes an arbitrary element from the set.
fn take_any(&mut self) -> Option
It is currently impossible to remove an element from a HashMap/HashSet through remove or take without a preexisting reference to an element/key of the set/map. So to have such reference the only way is to clone one beforehand:
fn take_any<T: Clone>(set: &mut HashSet<T>) -> Option<T> {
let result = set.iter().next()?.clone();
set.remove(&result);
result
}It is possible without the Clone bound with the drain_filter that allows to drain the first item and keep the rest, but it seems expansive to me.
fn take_any<T>(set: &mut HashSet<T>) -> Option<T> {
let mut taken = false;
set.drain_filter(|_| {
let take = !taken;
taken = true;
take
}).next()
}As for the name, it could also be named pop_any to reflect the pop_first and pop_last methods on BTreeSet and BTreeMap.