@@ -16,7 +16,8 @@ mod tests;
16
16
pub use self :: core:: raw_entry_v1:: { self , RawEntryApiV1 } ;
17
17
pub use self :: core:: { Entry , IndexedEntry , OccupiedEntry , VacantEntry } ;
18
18
pub use self :: iter:: {
19
- Drain , IntoIter , IntoKeys , IntoValues , Iter , IterMut , IterMut2 , Keys , Splice , Values , ValuesMut ,
19
+ Drain , ExtractIf , IntoIter , IntoKeys , IntoValues , Iter , IterMut , IterMut2 , Keys , Splice ,
20
+ Values , ValuesMut ,
20
21
} ;
21
22
pub use self :: mutable:: MutableEntryKey ;
22
23
pub use self :: mutable:: MutableKeys ;
@@ -36,7 +37,7 @@ use alloc::vec::Vec;
36
37
#[ cfg( feature = "std" ) ]
37
38
use std:: collections:: hash_map:: RandomState ;
38
39
39
- use self :: core:: IndexMapCore ;
40
+ pub ( crate ) use self :: core:: { ExtractCore , IndexMapCore } ;
40
41
use crate :: util:: { third, try_simplify_range} ;
41
42
use crate :: { Bucket , Entries , Equivalent , HashValue , TryReserveError } ;
42
43
@@ -306,6 +307,44 @@ impl<K, V, S> IndexMap<K, V, S> {
306
307
Drain :: new ( self . core . drain ( range) )
307
308
}
308
309
310
+ /// Creates an iterator which uses a closure to determine if an element should be removed.
311
+ ///
312
+ /// If the closure returns true, the element is removed from the map and yielded.
313
+ /// If the closure returns false, or panics, the element remains in the map and will not be
314
+ /// yielded.
315
+ ///
316
+ /// Note that `extract_if` lets you mutate every value in the filter closure, regardless of
317
+ /// whether you choose to keep or remove it.
318
+ ///
319
+ /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
320
+ /// or the iteration short-circuits, then the remaining elements will be retained.
321
+ /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
322
+ ///
323
+ /// [`retain`]: IndexMap::retain
324
+ ///
325
+ /// # Examples
326
+ ///
327
+ /// Splitting a map into even and odd keys, reusing the original map:
328
+ ///
329
+ /// ```
330
+ /// use indexmap::IndexMap;
331
+ ///
332
+ /// let mut map: IndexMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
333
+ /// let extracted: IndexMap<i32, i32> = map.extract_if(|k, _v| k % 2 == 0).collect();
334
+ ///
335
+ /// let evens = extracted.keys().copied().collect::<Vec<_>>();
336
+ /// let odds = map.keys().copied().collect::<Vec<_>>();
337
+ ///
338
+ /// assert_eq!(evens, vec![0, 2, 4, 6]);
339
+ /// assert_eq!(odds, vec![1, 3, 5, 7]);
340
+ /// ```
341
+ pub fn extract_if < F > ( & mut self , pred : F ) -> ExtractIf < ' _ , K , V , F >
342
+ where
343
+ F : FnMut ( & K , & mut V ) -> bool ,
344
+ {
345
+ ExtractIf :: new ( & mut self . core , pred)
346
+ }
347
+
309
348
/// Splits the collection into two at the given index.
310
349
///
311
350
/// Returns a newly allocated map containing the elements in the range
0 commit comments