@@ -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
@@ -307,6 +308,44 @@ impl<K, V, S> IndexMap<K, V, S> {
307
308
Drain :: new ( self . core . drain ( range) )
308
309
}
309
310
311
+ /// Creates an iterator which uses a closure to determine if an element should be removed.
312
+ ///
313
+ /// If the closure returns true, the element is removed from the map and yielded.
314
+ /// If the closure returns false, or panics, the element remains in the map and will not be
315
+ /// yielded.
316
+ ///
317
+ /// Note that `extract_if` lets you mutate every value in the filter closure, regardless of
318
+ /// whether you choose to keep or remove it.
319
+ ///
320
+ /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
321
+ /// or the iteration short-circuits, then the remaining elements will be retained.
322
+ /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
323
+ ///
324
+ /// [`retain`]: IndexMap::retain
325
+ ///
326
+ /// # Examples
327
+ ///
328
+ /// Splitting a map into even and odd keys, reusing the original map:
329
+ ///
330
+ /// ```
331
+ /// use indexmap::IndexMap;
332
+ ///
333
+ /// let mut map: IndexMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
334
+ /// let extracted: IndexMap<i32, i32> = map.extract_if(|k, _v| k % 2 == 0).collect();
335
+ ///
336
+ /// let evens = extracted.keys().copied().collect::<Vec<_>>();
337
+ /// let odds = map.keys().copied().collect::<Vec<_>>();
338
+ ///
339
+ /// assert_eq!(evens, vec![0, 2, 4, 6]);
340
+ /// assert_eq!(odds, vec![1, 3, 5, 7]);
341
+ /// ```
342
+ pub fn extract_if < F > ( & mut self , pred : F ) -> ExtractIf < ' _ , K , V , F >
343
+ where
344
+ F : FnMut ( & K , & mut V ) -> bool ,
345
+ {
346
+ ExtractIf :: new ( & mut self . core , pred)
347
+ }
348
+
310
349
/// Splits the collection into two at the given index.
311
350
///
312
351
/// Returns a newly allocated map containing the elements in the range
0 commit comments