itertools icon indicating copy to clipboard operation
itertools copied to clipboard

Feature Request: `single_result`

Open MasterTemple opened this issue 5 months ago • 1 comments

This is similar to partition_result. The idea is that instead of a collection of Ok values and a collection of Err values, it would return a single Result.

This is ideal for situations where you want to report all errors (not short-circuiting), and the Ok values only matter if there are no errors.

The implementation is below:

fn single_result<A, B, T, E>(self) -> Result<A, B>
where
    Self: Iterator<Item = Result<T, E>> + Sized,
    A: Default + Extend<T>,
    B: Default + Extend<T>,
{
    let mut is_err = false;
    let (a, b): (A, B) = self.partition_map(|r| match r {
        Ok(v) => Either::Left(v),
        Err(v) => {
            is_err = true;
            Either::Right(v)
        },
    });
    if is_err {
        Err(b)
    } else {
        Ok(a)
    }
}

Thank you for your time and consideration.

MasterTemple avatar Jun 14 '25 19:06 MasterTemple

Hi there, thanks for the idea, but couldn't this be done like this?

use itertools::Itertools;

fn main() {
    let (oks, errs) = dbg!(
        [Ok(1), Err("two"), Ok(3), Err("four")].into_iter()
            .partition_result::<Vec<_>, Vec<_>, _, _>()
    );
    if errs.is_empty() {
        dbg!(Err(errs)); // could be "return" instead
    } else {
        dbg!(Ok(oks)); // could be "return" instead
    }
}

The suggested implementation does not exploit the fact that we could stop collecting to A once is_err is set (deliberate choice?). And it does not give you information that might be relevant (because it discards "the other case" instead of just returning it).

tldr; I'm reluctant to introduce this into itertools. It seems to be syntactic sugar and does not do the heavy lifting.

phimuemue avatar Jun 16 '25 09:06 phimuemue