diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 7a79a472d58d9..4e5385c17e985 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1241,6 +1241,46 @@ impl HashMap self.search_mut(k).into_occupied_bucket().map(|bucket| pop_internal(bucket).1) } + /// Removes a key from the map, returning the stored key and value if the + /// key was previously in the map. + /// + /// The key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// [`Eq`]: ../../std/cmp/trait.Eq.html + /// [`Hash`]: ../../std/hash/trait.Hash.html + /// + /// # Examples + /// + /// ``` + /// #![feature(hash_map_remove_entry)] + /// use std::collections::HashMap; + /// + /// # fn main() { + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.remove_entry(&1), Some((1, "a"))); + /// assert_eq!(map.remove(&1), None); + /// # } + /// ``` + #[unstable(feature = "hash_map_remove_entry", issue = "46344")] + pub fn remove_entry(&mut self, k: &Q) -> Option<(K, V)> + where K: Borrow, + Q: Hash + Eq + { + if self.table.size() == 0 { + return None; + } + + self.search_mut(k) + .into_occupied_bucket() + .map(|bucket| { + let (k, v, _) = pop_internal(bucket); + (k, v) + }) + } + /// Retains only the elements specified by the predicate. /// /// In other words, remove all pairs `(k, v)` such that `f(&k,&mut v)` returns `false`. @@ -3040,13 +3080,21 @@ mod test_map { } #[test] - fn test_pop() { + fn test_remove() { let mut m = HashMap::new(); m.insert(1, 2); assert_eq!(m.remove(&1), Some(2)); assert_eq!(m.remove(&1), None); } + #[test] + fn test_remove_entry() { + let mut m = HashMap::new(); + m.insert(1, 2); + assert_eq!(m.remove_entry(&1), Some((1, 2))); + assert_eq!(m.remove(&1), None); + } + #[test] fn test_iterate() { let mut m = HashMap::with_capacity(4);