Skip to content

Commit 61c2a48

Browse files
committed
adds retain on slices
1 parent 0612568 commit 61c2a48

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/libcore/slice/mod.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,6 +2063,51 @@ impl<T> [T] {
20632063
self.partition_dedup_by(|a, b| key(a) == key(b))
20642064
}
20652065

2066+
/// Retains only the elements specified by the predicate.
2067+
///
2068+
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
2069+
/// This method operates in place, visiting each element exactly once in the
2070+
/// original order, and preserves the order of the retained elements.
2071+
///
2072+
/// # Examples
2073+
///
2074+
/// ```
2075+
/// #![feature(slice_retain)]
2076+
///
2077+
/// let mut slice = [1, 2, 3, 4];
2078+
/// let retained = slice.retain(|&x| x % 2 == 0);
2079+
/// assert_eq!(retained, [2, 4]);
2080+
/// ```
2081+
///
2082+
/// The exact order may be useful for tracking external state, like an index.
2083+
///
2084+
/// ```
2085+
/// #![feature(slice_retain)]
2086+
///
2087+
/// let mut slice = [1, 2, 3, 4, 5];
2088+
/// let keep = [false, true, true, false, true];
2089+
/// let mut i = 0;
2090+
/// let retained = slice.retain(|_| (keep[i], i += 1).0);
2091+
/// assert_eq!(retained, [2, 3, 5]);
2092+
/// ```
2093+
#[unstable(feature = "slice_retain", issue = "71831")]
2094+
#[must_use]
2095+
pub fn retain<F>(&mut self, mut f: F) -> &mut Self
2096+
where
2097+
F: FnMut(&T) -> bool,
2098+
{
2099+
let len = self.len();
2100+
let mut del = 0;
2101+
for i in 0..len {
2102+
if !f(&self[i]) {
2103+
del += 1;
2104+
} else if del > 0 {
2105+
self.swap(i - del, i);
2106+
}
2107+
}
2108+
self.split_at_mut(len - del).0
2109+
}
2110+
20662111
/// Rotates the slice in-place such that the first `mid` elements of the
20672112
/// slice move to the end while the last `self.len() - mid` elements move to
20682113
/// the front. After calling `rotate_left`, the element previously at index

src/libcore/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#![feature(leading_trailing_ones)]
4444
#![feature(const_forget)]
4545
#![feature(option_unwrap_none)]
46+
#![feature(slice_retain)]
4647

4748
extern crate test;
4849

0 commit comments

Comments
 (0)