Djent
Djent

Reputation: 3467

Build two vectors when iterating once over a iterable

I have an iterator of enum that has two variants. The iterator can be quite big, so I'd prefer to avoid iterating over it more than once. Is it possible to collect two vectors by iterating over it once?

Let's say I have a vector of numbers that are positive and negative. I'd like to kind-of sort them during iteration, which will result of two vectors - one with positive and other with negative numbers. Here's an example pseudocode:

let input = vec![1, -2, 4, -5, 3];

let (positive, negative) = input
    .iter()
    .some_magic_that_will_make_two_iterators()
    .collect::<(Vec<_>, Vec<_>)>();

assert_eq!(positive, vec![1, 4, 3]);
assert_eq!(negative, vec![-2, -5])

Is there any way to achieve that? I know that I can define positive and negative first, and just push items during iterating, but that won't be the optimal solution for big collections. In my real case, I expect that there may be around million enums in the initial iterable.

Upvotes: 1

Views: 145

Answers (1)

Masklinn
Masklinn

Reputation: 42197

Iterator::partition maybe?

It's eager so there is no collect step. It also can not map the elements when partitioning, so that might not work for your needs: it would work fine for partitioning positive and negative values, but it would not work to partition and unwrap two variants of an enum.

Is there any way to achieve that? I know that I can define positive and negative first, and just push items during iterating, but that won't be the optimal solution for big collections. In my real case, I expect that there may be around million enums in the initial iterable.

I don't see why not, it's pretty much what a partition function will do. And you might be able to size the target collections based on your understanding of the distribution, whereas a partition function would not be.

Upvotes: 2

Related Questions