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