Skip to content

Commit 50246b0

Browse files
committed
Implement slice::split_once and slice::rsplit_once
Feature gate is slice_split_once and tracking issue is #112811.
1 parent c911e08 commit 50246b0

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

library/core/src/slice/mod.rs

+56
Original file line numberDiff line numberDiff line change
@@ -2478,6 +2478,62 @@ impl<T> [T] {
24782478
RSplitNMut::new(self.rsplit_mut(pred), n)
24792479
}
24802480

2481+
/// Splits the slice on the first element that matches the specified
2482+
/// predicate.
2483+
///
2484+
/// If any matching elements are resent in the slice, returns the prefix
2485+
/// before the match and suffix after. The matching element itself is not
2486+
/// included. If no elements match, returns `None`.
2487+
///
2488+
/// # Examples
2489+
///
2490+
/// ```
2491+
/// #![feature(slice_split_once)]
2492+
/// let s = [1, 2, 3, 2, 4];
2493+
/// assert_eq!(s.split_once(|&x| x == 2), Some((
2494+
/// &[1][..],
2495+
/// &[3, 2, 4][..]
2496+
/// )));
2497+
/// assert_eq!(s.split_once(|&x| x == 0), None);
2498+
/// ```
2499+
#[unstable(feature = "slice_split_once", reason = "newly added", issue = "112811")]
2500+
#[inline]
2501+
pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
2502+
where
2503+
F: FnMut(&T) -> bool,
2504+
{
2505+
let index = self.iter().position(pred)?;
2506+
Some((&self[..index], &self[index + 1..]))
2507+
}
2508+
2509+
/// Splits the slice on the last element that matches the specified
2510+
/// predicate.
2511+
///
2512+
/// If any matching elements are resent in the slice, returns the prefix
2513+
/// before the match and suffix after. The matching element itself is not
2514+
/// included. If no elements match, returns `None`.
2515+
///
2516+
/// # Examples
2517+
///
2518+
/// ```
2519+
/// #![feature(slice_split_once)]
2520+
/// let s = [1, 2, 3, 2, 4];
2521+
/// assert_eq!(s.rsplit_once(|&x| x == 2), Some((
2522+
/// &[1, 2, 3][..],
2523+
/// &[4][..]
2524+
/// )));
2525+
/// assert_eq!(s.rsplit_once(|&x| x == 0), None);
2526+
/// ```
2527+
#[unstable(feature = "slice_split_once", reason = "newly added", issue = "112811")]
2528+
#[inline]
2529+
pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
2530+
where
2531+
F: FnMut(&T) -> bool,
2532+
{
2533+
let index = self.iter().rposition(pred)?;
2534+
Some((&self[..index], &self[index + 1..]))
2535+
}
2536+
24812537
/// Returns `true` if the slice contains an element with the given value.
24822538
///
24832539
/// This operation is *O*(*n*).

library/core/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#![feature(sort_internals)]
4848
#![feature(slice_take)]
4949
#![feature(slice_from_ptr_range)]
50+
#![feature(slice_split_once)]
5051
#![feature(split_as_slice)]
5152
#![feature(maybe_uninit_uninit_array)]
5253
#![feature(maybe_uninit_write_slice)]

library/core/tests/slice.rs

+20
Original file line numberDiff line numberDiff line change
@@ -2448,6 +2448,26 @@ fn slice_rsplit_array_mut_out_of_bounds() {
24482448
let _ = v.rsplit_array_mut::<7>();
24492449
}
24502450

2451+
#[test]
2452+
fn slice_split_once() {
2453+
let v = &[1, 2, 3, 2, 4][..];
2454+
2455+
assert_eq!(v.split_once(|&x| x == 2), Some((&[1][..], &[3, 2, 4][..])));
2456+
assert_eq!(v.split_once(|&x| x == 1), Some((&[][..], &[2, 3, 2, 4][..])));
2457+
assert_eq!(v.split_once(|&x| x == 4), Some((&[1, 2, 3, 2][..], &[][..])));
2458+
assert_eq!(v.split_once(|&x| x == 0), None);
2459+
}
2460+
2461+
#[test]
2462+
fn slice_rsplit_once() {
2463+
let v = &[1, 2, 3, 2, 4][..];
2464+
2465+
assert_eq!(v.rsplit_once(|&x| x == 2), Some((&[1, 2, 3][..], &[4][..])));
2466+
assert_eq!(v.rsplit_once(|&x| x == 1), Some((&[][..], &[2, 3, 2, 4][..])));
2467+
assert_eq!(v.rsplit_once(|&x| x == 4), Some((&[1, 2, 3, 2][..], &[][..])));
2468+
assert_eq!(v.rsplit_once(|&x| x == 0), None);
2469+
}
2470+
24512471
macro_rules! take_tests {
24522472
(slice: &[], $($tts:tt)*) => {
24532473
take_tests!(ty: &[()], slice: &[], $($tts)*);

0 commit comments

Comments
 (0)