4 releases
0.1.0 | Jan 28, 2024 |
---|---|
0.1.0-alpha.1 | Mar 24, 2023 |
0.0.2 | Mar 12, 2023 |
0.0.1 | Mar 12, 2023 |
#646 in Algorithms
2,823 downloads per month
Used in 5 crates
(via lsm-tree)
45KB
724 lines
Double-Ended Peekable
A very small crate providing an additional abstraction over Iterator
, in
order to lift the concepts introduced by Peekable
over
DoubleEndedIterator
.
The reason
With Peekable
you can use peek
in order to get a reference to the upcoming
element from the iterator, and you can also use next_if
/next_if_eq
in
order to advance the iterator only when the upcoming element satisfies some
conditions.
However, this abstraction does not work well when you need to perform these
operations from both the start and the end of a double-ended iterator. For
instance, you cannot just do .by_ref().rev().peekable().peek().next()
on the
fly, because even if this approach seems to work, the implementation need to
store the next element (the corresponding of next_back
, to be clearer)
inside the instance of Peekable
, which means that the peeked element is
going to be dropped using the snippet just shown.
How to use
You just need to import the extension trait DoubleEndedPeekableExt
in
order to easily use the double_ended_peekable
:
use double_ended_peekable::DoubleEndedPeekableExt;
let mut iter = [0, 1, 2, 3, 4].into_iter().double_ended_peekable();
assert_eq!(
iter.next_front_back_if(|a, b| a % 2 == 0 && b % 2 == 0),
Some((0, 4))
);
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next_back(), Some(3));
assert_eq!(iter.peek(), Some(&2));
assert_eq!(iter.peek_back(), Some(&2));
assert_eq!(iter.next_front_back_if_eq(&2, &2), None);
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
Keep in mind that DoubleEndedPeekableExt
is implemented for every
Iterator
, but some of the methods of DoubleEndedPeekable
are only
implemented for types that implement DoubleEndedIterator
.
Features
-
All the abstractions from
Peekable
. -
The
*_back_*
variants of the methods provided byPeekable
:All these methods work like their front version, except they operate from the end to the beginning of the iterator (just like
DoubleEndedIterator
does). -
next_front_back_if
: it advances both forward and backward sides of the iterator if a condition is satisfied. The condition is expressed by a function that takes a reference to the next and the next-back elements and it returns a boolean, which indicates whether the sides of the iterator need to be advanced. -
next_front_back_if_eq
: similar tonext_front_back_if
, except it directly takes the references to the next and the next-back elements instead of a function.