Add .retain() method
Based on "retain_mut" as discussed for vec: we can provide &mut to the element to remove effortlessly.
This commit is contained in:
+34
@@ -277,6 +277,40 @@ impl<A: Array> ArrayVec<A> {
|
|||||||
while let Some(_) = self.pop() { }
|
while let Some(_) = self.pop() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retains only the elements specified by the predicate.
|
||||||
|
///
|
||||||
|
/// In other words, remove all elements `e` such that `f(&mut e)` returns false.
|
||||||
|
/// This method operates in place and preserves the order of the retained
|
||||||
|
/// elements.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use arrayvec::ArrayVec;
|
||||||
|
///
|
||||||
|
/// let mut array = ArrayVec::from([1, 2, 3, 4]);
|
||||||
|
/// array.retain(|x| *x & 1 != 0 );
|
||||||
|
/// assert_eq!(&array[..], &[1, 3]);
|
||||||
|
/// ```
|
||||||
|
pub fn retain<F>(&mut self, mut f: F)
|
||||||
|
where F: FnMut(&mut A::Item) -> bool
|
||||||
|
{
|
||||||
|
let len = self.len();
|
||||||
|
let mut del = 0;
|
||||||
|
{
|
||||||
|
let v = &mut **self;
|
||||||
|
|
||||||
|
for i in 0..len {
|
||||||
|
if !f(&mut v[i]) {
|
||||||
|
del += 1;
|
||||||
|
} else if del > 0 {
|
||||||
|
v.swap(i - del, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if del > 0 {
|
||||||
|
self.drain(len - del..);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the vector's length without dropping or moving out elements
|
/// Set the vector's length without dropping or moving out elements
|
||||||
///
|
///
|
||||||
/// May panic if `length` is greater than the capacity.
|
/// May panic if `length` is greater than the capacity.
|
||||||
|
|||||||
@@ -158,6 +158,23 @@ fn test_drain() {
|
|||||||
assert_eq!(&v[..], &[]);
|
assert_eq!(&v[..], &[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_retain() {
|
||||||
|
let mut v = ArrayVec::from([0; 8]);
|
||||||
|
for (i, elt) in v.iter_mut().enumerate() {
|
||||||
|
*elt = i;
|
||||||
|
}
|
||||||
|
v.retain(|_| true);
|
||||||
|
assert_eq!(&v[..], &[0, 1, 2, 3, 4, 5, 6, 7]);
|
||||||
|
v.retain(|elt| {
|
||||||
|
*elt /= 2;
|
||||||
|
*elt % 2 == 0
|
||||||
|
});
|
||||||
|
assert_eq!(&v[..], &[0, 0, 2, 2]);
|
||||||
|
v.retain(|_| false);
|
||||||
|
assert_eq!(&v[..], &[]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_drain_oob() {
|
fn test_drain_oob() {
|
||||||
|
|||||||
Reference in New Issue
Block a user