Trait rand::seq::IteratorRandom

source ·
pub trait IteratorRandom: Iterator + Sized {
    // Provided methods
    fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
       where R: Rng + ?Sized { ... }
    fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
       where R: Rng + ?Sized { ... }
    fn choose_multiple_fill<R>(
        self,
        rng: &mut R,
        buf: &mut [Self::Item]
    ) -> usize
       where R: Rng + ?Sized { ... }
    fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
       where R: Rng + ?Sized { ... }
}
Expand description

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 rand::seq::IteratorRandom;

let mut rng = rand::thread_rng();

let faces = "😀😎😐😕😠😢";
println!("I am {}!", faces.chars().choose(&mut rng).unwrap());

Example output (non-deterministic):

I am 😀!

Provided Methods§

source

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where R: Rng + ?Sized,

Uniformly sample one element

Assuming that the Iterator::size_hint is correct, this method returns one uniformly-sampled random element of the slice, or None only if the slice is empty. Incorrect bounds on the size_hint may cause this method to incorrectly return None if fewer elements than the advertised lower bound are present and may prevent sampling of elements beyond an advertised upper bound (i.e. incorrect size_hint is memory-safe, but may result in unexpected None result and non-uniform distribution).

With an accurate Iterator::size_hint and where Iterator::nth is a constant-time operation, this method can offer O(1) performance. Where no size hint is available, complexity is O(n) where n is the iterator length. Partial hints (where lower > 0) also improve performance.

Note further that Iterator::size_hint may affect the number of RNG samples used as well as the result (while remaining uniform sampling). Consider instead using IteratorRandom::choose_stable to avoid Iterator combinators which only change size hints from affecting the results.

source

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where R: Rng + ?Sized,

Uniformly sample one element (stable)

This method is very similar to choose except that the result only depends on the length of the iterator and the values produced by rng. Notably for any iterator of a given length this will make the same requests to rng and if the same sequence of values are produced the same index will be selected from self. 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 prefer choose.

Note that this method still uses Iterator::size_hint to skip constructing elements where possible, however the selection and rng calls are the same in the face of this optimization. If you want to force every element to be created regardless call .inspect(|e| ()).

source

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where R: Rng + ?Sized,

Uniformly sample amount distinct elements into a buffer

Collects 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) where n is the length of the iterator. For slices, prefer IndexedRandom::choose_multiple.

source

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where R: Rng + ?Sized,

Available on crate feature alloc only.

Uniformly sample amount distinct elements into a Vec

This is equivalent to choose_multiple_fill except 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 amount unless the iterator contains insufficient elements, in which case it equals the number of elements available.

Complexity is O(n) where n is the length of the iterator. For slices, prefer IndexedRandom::choose_multiple.

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<I> IteratorRandom for I
where I: Iterator + Sized,