Trait IteratorRandom
trait IteratorRandom: Iterator + Sized
Extension trait on iterators, providing random sampling methods.
This trait is implemented on all iterators I where I: Iterator + Sized
and provides methods for
choosing one or more elements. You must use this trait:
use IteratorRandom;
let faces = "😀😎😐😕😠😢";
println!;
Example output (non-deterministic):
I am 😀!
Provided Methods
fn choose<R>(self: Self, rng: &mut R) -> Option<<Self as >::Item> where R: Rng + ?SizedUniformly sample one element
Assuming that the
Iterator::size_hintis correct, this method returns one uniformly-sampled random element of the slice, orNoneonly if the slice is empty. Incorrect bounds on thesize_hintmay cause this method to incorrectly returnNoneif fewer elements than the advertisedlowerbound are present and may prevent sampling of elements beyond an advertisedupperbound (i.e. incorrectsize_hintis memory-safe, but may result in unexpectedNoneresult and non-uniform distribution).With an accurate
Iterator::size_hintand whereIterator::nthis a constant-time operation, this method can offerO(1)performance. Where no size hint is available, complexity isO(n)wherenis the iterator length. Partial hints (wherelower > 0) also improve performance.Note further that
Iterator::size_hintmay affect the number of RNG samples used as well as the result (while remaining uniform sampling). Consider instead usingIteratorRandom::choose_stableto avoidIteratorcombinators which only change size hints from affecting the results.Example
use IteratorRandom; let words = "Mary had a little lamb".split; println!;fn choose_stable<R>(self: Self, rng: &mut R) -> Option<<Self as >::Item> where R: Rng + ?SizedUniformly sample one element (stable)
This method is very similar to
chooseexcept that the result only depends on the length of the iterator and the values produced byrng. Notably for any iterator of a given length this will make the same requests torngand if the same sequence of values are produced the same index will be selected fromself. This may be useful if you need consistent results no matter what type of iterator you are working with. If you do not need this stability preferchoose.Note that this method still uses
Iterator::size_hintto skip constructing elements where possible, however the selection andrngcalls are the same in the face of this optimization. If you want to force every element to be created regardless call.inspect(|e| ()).fn choose_multiple_fill<R>(self: Self, rng: &mut R, buf: &mut [<Self as >::Item]) -> usize where R: Rng + ?SizedUniformly sample
amountdistinct elements into a bufferCollects values at random from the iterator into a supplied buffer until that buffer is filled.
Although the elements are selected randomly, the order of elements in the buffer is neither stable nor fully random. If random ordering is desired, shuffle the result.
Returns the number of elements added to the buffer. This equals the length of the buffer unless the iterator contains insufficient elements, in which case this equals the number of elements available.
Complexity is
O(n)wherenis the length of the iterator. For slices, preferIndexedRandom::choose_multiple.fn choose_multiple<R>(self: Self, rng: &mut R, amount: usize) -> Vec<<Self as >::Item> where R: Rng + ?SizedUniformly sample
amountdistinct elements into aVecThis is equivalent to
choose_multiple_fillexcept for the result type.Although the elements are selected randomly, the order of elements in the buffer is neither stable nor fully random. If random ordering is desired, shuffle the result.
The length of the returned vector equals
amountunless the iterator contains insufficient elements, in which case it equals the number of elements available.Complexity is
O(n)wherenis the length of the iterator. For slices, preferIndexedRandom::choose_multiple.
Implementors
impl<I> IteratorRandom for IndexVecIter<'a>impl<I> IteratorRandom for Iter<D, R, T>impl<I> IteratorRandom for Iimpl<I> IteratorRandom for SliceChooseIter<'a, S, T>impl<I> IteratorRandom for IndexVecIntoIter