Skip to content

Add split and split_inclusive#1060

Closed
A4-Tacks wants to merge 1 commit into
rust-itertools:masterfrom
A4-Tacks:add-split-method
Closed

Add split and split_inclusive#1060
A4-Tacks wants to merge 1 commit into
rust-itertools:masterfrom
A4-Tacks:add-split-method

Conversation

@A4-Tacks

Copy link
Copy Markdown

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.

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

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]);

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]);
```
@phimuemue

Copy link
Copy Markdown
Member

Hi there. Honestly, I doubt this is really required from an API prospective, because afaik it can be expressed in terms of partition: the predicate can capture an outer bool that is flipped at the "partition point" and be returned. This "trick" might be a bit less efficient but has the advantage that it uses known functions (as opposed to the new split) - and, as a corollary, avoids the question what split should do on the second true (flip to the other container again, or ignore it).

Thus, I suggest to close this.

@phimuemue

Copy link
Copy Markdown
Member

Closing this. It can straightforwardly be implemented in terms of partition:

    { // split
        let nums = vec![0, 1, 2, 3, 4, 5];
    
        let mut put_into_first_container = true;
        let (a, b): (Vec<_>, Vec<_>) = nums.into_iter().partition(|n| {
            put_into_first_container &= *n == 3;
            put_into_first_container
        });
        
        assert_eq!(a, [0, 1, 2]);
        assert_eq!(b, [3, 4, 5]);    
    }
    
    { // split_inclusive
        let nums = vec![0, 1, 2, 3, 4, 5];

        let mut put_into_first_container = true;
        let (a, b): (Vec<_>, Vec<_>) = nums.into_iter().partition(|n| {
            let put_into_first_container_before = put_into_first_container;
            put_into_first_container &= *n == 3;
            put_into_first_container_before
        });
        
        assert_eq!(a, [0, 1, 2, 3]);
        assert_eq!(b, [4, 5]);    
    }

@phimuemue phimuemue closed this Sep 22, 2025
@A4-Tacks

Copy link
Copy Markdown
Author

The implementation of split uses extend, so that B can obtain a good size_hint to reduce allocation

@phimuemue

Copy link
Copy Markdown
Member

The implementation of split uses extend, so that B can obtain a good size_hint to reduce allocation

True, but at the cost that "swithing to the other container" is possible at most once. This begs the question "what does split do when it encounters true a second time"?

On top, it still does the extend(once(...)) for A, and if maximum performance is needed, then possibly neither partition nor split is your best bet, so I argue that users should either go with the simple partition that can emulate your split, or - if performance is needed - use a bespoke solution.

@A4-Tacks

Copy link
Copy Markdown
Author

Okay, although the split method can make things easier, it still lacks necessity

Using external flags to mark split points is really cumbersome and semantically ambiguous ...

@A4-Tacks

Copy link
Copy Markdown
Author

Closing this. It can straightforwardly be implemented in terms of partition

If the judgment conditions are complex, it is necessary to replace x &= ... with x = x && ...,
otherwise there will be additional costs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants