Skip to content

Commit 02a78ac

Browse files
committed
Add split and split_inclusive
Collect all iterator elements into one of two partitions. Unlike [`Iterator::partition`], when predicate returns true for the first time, it collects this element and all rest elements into B. ```rust use itertools::Itertools; let nums = vec![0, 1, 2, 3, 4, 5]; let (a, b): (Vec<_>, Vec<_>) = nums.into_iter().split(|n| *n == 3); assert_eq!(a, [0, 1, 2]); assert_eq!(b, [3, 4, 5]); ``` --- Collect all iterator elements into one of two partitions. Unlike [`Itertools::split`], when predicate returns true, the element is collected into A ```rust use itertools::Itertools; let nums = vec![0, 1, 2, 3, 4, 5]; let (a, b): (Vec<_>, Vec<_>) = nums.into_iter().split_inclusive(|n| *n == 3); assert_eq!(a, [0, 1, 2, 3]); assert_eq!(b, [4, 5]); ```
1 parent 61c5a7a commit 02a78ac

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

src/lib.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3701,6 +3701,77 @@ pub trait Itertools: Iterator {
37013701
(left, right)
37023702
}
37033703

3704+
/// Collect all iterator elements into one of two partitions.
3705+
/// Unlike [`Iterator::partition`], when predicate returns true for the first time,
3706+
/// it collects this element and all rest elements into `B`.
3707+
///
3708+
/// ```
3709+
/// use itertools::Itertools;
3710+
///
3711+
/// let nums = vec![0, 1, 2, 3, 4, 5];
3712+
///
3713+
/// let (a, b): (Vec<_>, Vec<_>) = nums.into_iter().split(|n| *n == 3);
3714+
///
3715+
/// assert_eq!(a, [0, 1, 2]);
3716+
/// assert_eq!(b, [3, 4, 5]);
3717+
/// ```
3718+
fn split<A, B, P>(mut self, mut predicate: P) -> (A, B)
3719+
where
3720+
Self: Sized,
3721+
P: FnMut(&Self::Item) -> bool,
3722+
A: Default + Extend<Self::Item>,
3723+
B: Default + Extend<Self::Item>,
3724+
{
3725+
let mut collect_a = A::default();
3726+
let mut collect_b = B::default();
3727+
3728+
while let Some(elem) = self.next() {
3729+
if predicate(&elem) {
3730+
collect_b.extend(once(elem));
3731+
break;
3732+
}
3733+
collect_a.extend(once(elem));
3734+
}
3735+
collect_b.extend(self);
3736+
3737+
(collect_a, collect_b)
3738+
}
3739+
3740+
/// Collect all iterator elements into one of two partitions.
3741+
/// Unlike [`Itertools::split`], when predicate returns true, the element is collected into `A`.
3742+
///
3743+
/// ```
3744+
/// use itertools::Itertools;
3745+
///
3746+
/// let nums = vec![0, 1, 2, 3, 4, 5];
3747+
///
3748+
/// let (a, b): (Vec<_>, Vec<_>) = nums.into_iter().split_inclusive(|n| *n == 3);
3749+
///
3750+
/// assert_eq!(a, [0, 1, 2, 3]);
3751+
/// assert_eq!(b, [4, 5]);
3752+
/// ```
3753+
fn split_inclusive<A, B, P>(mut self, mut predicate: P) -> (A, B)
3754+
where
3755+
Self: Sized,
3756+
P: FnMut(&Self::Item) -> bool,
3757+
A: Default + Extend<Self::Item>,
3758+
B: Default + Extend<Self::Item>,
3759+
{
3760+
let mut collect_a = A::default();
3761+
let mut collect_b = B::default();
3762+
3763+
while let Some(elem) = self.next() {
3764+
let is_split_point = predicate(&elem);
3765+
collect_a.extend(once(elem));
3766+
if is_split_point {
3767+
break;
3768+
}
3769+
}
3770+
collect_b.extend(self);
3771+
3772+
(collect_a, collect_b)
3773+
}
3774+
37043775
/// Partition a sequence of `Result`s into one list of all the `Ok` elements
37053776
/// and another list of all the `Err` elements.
37063777
///

0 commit comments

Comments
 (0)