rust-itertools / itertools

Extra iterator adaptors, iterator methods, free functions, and macros.
https://docs.rs/itertools/
Apache License 2.0
2.76k stars 309 forks source link

Add single-element tuple for `collect_tuple` #953

Closed amab8901 closed 5 months ago

amab8901 commented 5 months ago

I'm trying to select exactly one element via let the_one = vector.iter().filter(|item| item == condition).collect_tuple(). It needs to match exactly one element, no more, no less. If 2 elements are in the iterator after the filter, then that's an error (due to ambiguity on which item to use later in the code).

The .first() and .last() and .next() methods on iterators don't work because they don't guarantee that there's only one element in the vector/iterator.

Philippe-Cholet commented 5 months ago

What about Itertools::exactly_one?

let the_one = vector.iter().exactly_one().map_err(|it| ..)?;

phimuemue commented 5 months ago

For the sake of completeness: 1-element tuples are supported, but you may need type annotations:

    let vector = vec![1,2,3,4];
    let the_one : Option<(_,)> = dbg!(vector.iter().filter(|item| **item >= 2).collect_tuple());
    //                     ^
    //                     |
    //                     +-- Note the comma to signify a 1-element tuple.
amab8901 commented 5 months ago

What about Itertools::exactly_one?

let the_one = vector.iter().exactly_one().map_err(|it| ..)?;

oh, I didn't see that one, thanks!