@@ -557,7 +557,7 @@ impl<K: Ord, V> TreeMap<K, V> {
557
557
/// ```
558
558
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
559
559
pub fn remove ( & mut self , key : & K ) -> Option < V > {
560
- let ret = remove ( & mut self . root , key) ;
560
+ let ret = remove ( & mut self . root , |x| key. cmp ( x ) ) ;
561
561
if ret. is_some ( ) { self . length -= 1 }
562
562
ret
563
563
}
@@ -618,6 +618,33 @@ impl<K, V> TreeMap<K, V> {
618
618
}
619
619
}
620
620
621
+ impl < K : Ord , V > TreeMap < K , V > {
622
+ /// Returns the value for which `f(key)` returns `Equal`. `f` is invoked
623
+ /// with current key and guides tree navigation. That means `f` should
624
+ /// be aware of natural ordering of the tree.
625
+ ///
626
+ /// # Example
627
+ ///
628
+ /// ```
629
+ /// use std::collections::TreeMap;
630
+ ///
631
+ /// let mut t = TreeMap::new();
632
+ /// t.insert("Content-Type".to_string(), "application/xml".to_string());
633
+ /// t.insert("User-Agent".to_string(), "Curl-Rust/0.1".to_string());
634
+ ///
635
+ /// match t.remove_with(|k| "User-Agent".cmp(k.as_slice())) {
636
+ /// Some(x) => assert_eq!(x.as_slice(), "Curl-Rust/0.1"),
637
+ /// None => panic!(),
638
+ /// }
639
+ ///
640
+ /// assert_eq!(t.find_with(|x| "User-Agent".cmp(x.as_slice())), None);
641
+ /// ```
642
+ #[ inline]
643
+ pub fn remove_with ( & mut self , f: |& K | -> Ordering ) -> Option < V > {
644
+ remove ( & mut self . root , f)
645
+ }
646
+ }
647
+
621
648
// range iterators.
622
649
623
650
macro_rules! bound_setup {
@@ -1169,7 +1196,7 @@ fn insert<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
1169
1196
}
1170
1197
1171
1198
fn remove < K : Ord , V > ( node : & mut Option < Box < TreeNode < K , V > > > ,
1172
- key : & K ) -> Option < V > {
1199
+ f : | & K | -> Ordering ) -> Option < V > {
1173
1200
fn heir_swap < K : Ord , V > ( node : & mut Box < TreeNode < K , V > > ,
1174
1201
child : & mut Option < Box < TreeNode < K , V > > > ) {
1175
1202
// *could* be done without recursion, but it won't borrow check
@@ -1188,9 +1215,9 @@ fn remove<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
1188
1215
return None ; // bottom of tree
1189
1216
}
1190
1217
Some ( ref mut save) => {
1191
- let ( ret, rebalance) = match key . cmp ( & save. key ) {
1192
- Less => ( remove ( & mut save. left , key ) , true ) ,
1193
- Greater => ( remove ( & mut save. right , key ) , true ) ,
1218
+ let ( ret, rebalance) = match f ( & save. key ) {
1219
+ Less => ( remove ( & mut save. left , f ) , true ) ,
1220
+ Greater => ( remove ( & mut save. right , f ) , true ) ,
1194
1221
Equal => {
1195
1222
if save. left . is_some ( ) {
1196
1223
if save. right . is_some ( ) {
@@ -1202,7 +1229,7 @@ fn remove<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
1202
1229
swap ( & mut save. value , & mut left. value ) ;
1203
1230
}
1204
1231
save. left = Some ( left) ;
1205
- ( remove ( & mut save. left , key ) , true )
1232
+ ( remove ( & mut save. left , f ) , true )
1206
1233
} else {
1207
1234
let new = save. left . take ( ) . unwrap ( ) ;
1208
1235
let box TreeNode { value, ..} = replace ( save, new) ;
@@ -1810,6 +1837,15 @@ mod test_treemap {
1810
1837
assert_eq ! ( m. remove( & 1 ) , Some ( 2 ) ) ;
1811
1838
assert_eq ! ( m. remove( & 1 ) , None ) ;
1812
1839
}
1840
+
1841
+ #[ test]
1842
+ fn test_remove_with ( ) {
1843
+ let mut m = TreeMap :: new ( ) ;
1844
+ m. insert ( 1 u, 2 i) ;
1845
+ assert_eq ! ( m. remove_with( |k| k. cmp( & 1 ) ) , Some ( 2 ) ) ;
1846
+ assert_eq ! ( m. remove( & 1 ) , None ) ;
1847
+ assert_eq ! ( m. remove_with( |k| k. cmp( & 1 ) ) , None ) ;
1848
+ }
1813
1849
}
1814
1850
1815
1851
#[ cfg( test) ]
0 commit comments