//! Extract elements from a vector based on supplied criteria //! //! *Project by [SnS Development](https://gitlab.com/SnSDev)* //! //! # Problem //! //! Need to filter some elements out of an existing Vector through a mutable //! borrow //! //! # Solution //! //! A trait implemented on `Vec` with 2 functions `remove_if` and //! `swap_remove_if` that iterate over elements, runs a supplied closure, //! and removes elements where the closure returns [true]. //! //! # Example //! ``` //! use vec_remove_if::VecRemoveIf; //! let mut v = vec![1, 12, 3, 14, 5, 16, 7, 18]; //! //! assert_eq!( //! vec![12, 14, 16, 18], //! v.remove_if(|e| e > &10) //! ); //! assert_eq!( //! vec![1, 3, 5, 7], //! v //! ); //! ``` #![warn(missing_docs)] /// Add [Self::remove_if] and [Self::swap_remove_if] to [Vec] pub trait VecRemoveIf { /// Run [Vec::remove] on each element in a vec when `closure` returns true /// /// # Example /// /// ``` /// use vec_remove_if::VecRemoveIf; /// let mut v = vec![1, 2, 3, 4, 5, 6, 7, 8]; /// /// assert_eq!( /// vec![1, 2, 3], /// v.remove_if(|e| e < &4) /// ); /// assert_eq!( /// vec![4, 5, 6, 7, 8], /// v /// ); /// ``` fn remove_if bool>(&mut self, closure: F) -> Vec; /// Run [Vec::swap_remove] on each element in a vec when `closure` returns true /// /// [Self::swap_remove_if] is more efficient, but does not preserve the /// element order of the vector (See [Vec::swap_remove]). /// /// # Example /// /// ``` /// use vec_remove_if::VecRemoveIf; /// let mut v = vec![1, 2, 3, 4, 5, 6, 7, 8]; /// /// assert_eq!( /// vec![1, 2, 3], /// v.swap_remove_if(|e| e < &4) /// ); /// assert_eq!( /// vec![8, 7, 6, 4, 5], /// v /// ); /// ``` fn swap_remove_if bool>(&mut self, closure: F) -> Vec; } impl VecRemoveIf for Vec { fn remove_if bool>(&mut self, closure: F) -> Vec { common(self, closure, &mut Vec::remove) } fn swap_remove_if bool>(&mut self, closure: F) -> Vec { common(self, closure, &mut Vec::swap_remove) } } fn common bool, A: FnMut(&mut Vec, usize) -> T>( v: &mut Vec, closure: F, action: &mut A, ) -> Vec { let mut i = 0; let mut r = Vec::new(); while i < v.len() { if closure(&v[i]) { r.push(action(v, i)) } else { i += 1; } } r }