Skip to content

Commit 11af29e

Browse files
committed
Auto merge of rust-lang#112818 - Benjamin-L:add-slice_split_once, r=cuviper
Implement `slice::split_once` and `slice::rsplit_once` Feature gate is `slice_split_once` and tracking issue is rust-lang#112811. These are equivalents to the existing `str::split_once` and `str::rsplit_once` methods.
2 parents 14d9510 + 84a3a0f commit 11af29e

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

core/src/slice/mod.rs

+56
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,62 @@ impl<T> [T] {
24822482
RSplitNMut::new(self.rsplit_mut(pred), n)
24832483
}
24842484

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

core/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#![feature(sort_internals)]
5050
#![feature(slice_take)]
5151
#![feature(slice_from_ptr_range)]
52+
#![feature(slice_split_once)]
5253
#![feature(split_as_slice)]
5354
#![feature(maybe_uninit_uninit_array)]
5455
#![feature(maybe_uninit_write_slice)]

core/tests/slice.rs

+20
Original file line numberDiff line numberDiff line change
@@ -2476,6 +2476,26 @@ fn slice_rsplit_array_mut_out_of_bounds() {
24762476
let _ = v.rsplit_array_mut::<7>();
24772477
}
24782478

2479+
#[test]
2480+
fn slice_split_once() {
2481+
let v = &[1, 2, 3, 2, 4][..];
2482+
2483+
assert_eq!(v.split_once(|&x| x == 2), Some((&[1][..], &[3, 2, 4][..])));
2484+
assert_eq!(v.split_once(|&x| x == 1), Some((&[][..], &[2, 3, 2, 4][..])));
2485+
assert_eq!(v.split_once(|&x| x == 4), Some((&[1, 2, 3, 2][..], &[][..])));
2486+
assert_eq!(v.split_once(|&x| x == 0), None);
2487+
}
2488+
2489+
#[test]
2490+
fn slice_rsplit_once() {
2491+
let v = &[1, 2, 3, 2, 4][..];
2492+
2493+
assert_eq!(v.rsplit_once(|&x| x == 2), Some((&[1, 2, 3][..], &[4][..])));
2494+
assert_eq!(v.rsplit_once(|&x| x == 1), Some((&[][..], &[2, 3, 2, 4][..])));
2495+
assert_eq!(v.rsplit_once(|&x| x == 4), Some((&[1, 2, 3, 2][..], &[][..])));
2496+
assert_eq!(v.rsplit_once(|&x| x == 0), None);
2497+
}
2498+
24792499
macro_rules! take_tests {
24802500
(slice: &[], $($tts:tt)*) => {
24812501
take_tests!(ty: &[()], slice: &[], $($tts)*);

0 commit comments

Comments
 (0)