@@ -497,6 +497,50 @@ impl<K, V, S> HashMap<K, V, S> {
497
497
Drain { base : self . base . drain ( ) }
498
498
}
499
499
500
+ /// Creates an iterator which uses a closure to determine if an element should be removed.
501
+ ///
502
+ /// If the closure returns true, the element is removed from the map and yielded.
503
+ /// If the closure returns false, or panics, the element remains in the map and will not be
504
+ /// yielded.
505
+ ///
506
+ /// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of
507
+ /// whether you choose to keep or remove it.
508
+ ///
509
+ /// If the iterator is only partially consumed or not consumed at all, each of the remaining
510
+ /// elements will still be subjected to the closure and removed and dropped if it returns true.
511
+ ///
512
+ /// It is unspecified how many more elements will be subjected to the closure
513
+ /// if a panic occurs in the closure, or a panic occurs while dropping an element,
514
+ /// or if the `DrainFilter` value is leaked.
515
+ ///
516
+ /// # Examples
517
+ ///
518
+ /// Splitting a map into even and odd keys, reusing the original map:
519
+ ///
520
+ /// ```
521
+ /// #![feature(hash_drain_filter)]
522
+ /// use std::collections::HashMap;
523
+ ///
524
+ /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
525
+ /// let drained: HashMap<i32, i32> = map.drain_filter(|k, _v| k % 2 == 0).collect();
526
+ ///
527
+ /// let mut evens = drained.keys().copied().collect::<Vec<_>>();
528
+ /// let mut odds = map.keys().copied().collect::<Vec<_>>();
529
+ /// evens.sort();
530
+ /// odds.sort();
531
+ ///
532
+ /// assert_eq!(evens, vec![0, 2, 4, 6]);
533
+ /// assert_eq!(odds, vec![1, 3, 5, 7]);
534
+ /// ```
535
+ #[ inline]
536
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
537
+ pub fn drain_filter < F > ( & mut self , pred : F ) -> DrainFilter < ' _ , K , V , F >
538
+ where
539
+ F : FnMut ( & K , & mut V ) -> bool ,
540
+ {
541
+ DrainFilter { base : self . base . drain_filter ( pred) }
542
+ }
543
+
500
544
/// Clears the map, removing all key-value pairs. Keeps the allocated memory
501
545
/// for reuse.
502
546
///
@@ -1190,6 +1234,19 @@ impl<'a, K, V> Drain<'a, K, V> {
1190
1234
}
1191
1235
}
1192
1236
1237
+ /// A draining, filtering iterator over the entries of a `HashMap`.
1238
+ ///
1239
+ /// This `struct` is created by the [`drain_filter`] method on [`HashMap`].
1240
+ ///
1241
+ /// [`drain_filter`]: HashMap::drain_filter
1242
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
1243
+ pub struct DrainFilter < ' a , K , V , F >
1244
+ where
1245
+ F : FnMut ( & K , & mut V ) -> bool ,
1246
+ {
1247
+ base : base:: DrainFilter < ' a , K , V , F > ,
1248
+ }
1249
+
1193
1250
/// A mutable iterator over the values of a `HashMap`.
1194
1251
///
1195
1252
/// This `struct` is created by the [`values_mut`] method on [`HashMap`]. See its
@@ -1990,6 +2047,36 @@ where
1990
2047
}
1991
2048
}
1992
2049
2050
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
2051
+ impl < K , V , F > Iterator for DrainFilter < ' _ , K , V , F >
2052
+ where
2053
+ F : FnMut ( & K , & mut V ) -> bool ,
2054
+ {
2055
+ type Item = ( K , V ) ;
2056
+
2057
+ #[ inline]
2058
+ fn next ( & mut self ) -> Option < ( K , V ) > {
2059
+ self . base . next ( )
2060
+ }
2061
+ #[ inline]
2062
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2063
+ self . base . size_hint ( )
2064
+ }
2065
+ }
2066
+
2067
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
2068
+ impl < K , V , F > FusedIterator for DrainFilter < ' _ , K , V , F > where F : FnMut ( & K , & mut V ) -> bool { }
2069
+
2070
+ #[ unstable( feature = "hash_drain_filter" , issue = "59618" ) ]
2071
+ impl < ' a , K , V , F > fmt:: Debug for DrainFilter < ' a , K , V , F >
2072
+ where
2073
+ F : FnMut ( & K , & mut V ) -> bool ,
2074
+ {
2075
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2076
+ f. pad ( "DrainFilter { .. }" )
2077
+ }
2078
+ }
2079
+
1993
2080
impl < ' a , K , V > Entry < ' a , K , V > {
1994
2081
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1995
2082
/// Ensures a value is in the entry by inserting the default if empty, and returns
0 commit comments