rand::seq

Trait IndexedRandom

source
pub trait IndexedRandom: Index<usize> {
    // Required method
    fn len(&self) -> usize;

    // Provided methods
    fn is_empty(&self) -> bool { ... }
    fn choose<R>(&self, rng: &mut R) -> Option<&Self::Output>
       where R: Rng + ?Sized { ... }
    fn choose_multiple<R>(
        &self,
        rng: &mut R,
        amount: usize,
    ) -> SliceChooseIter<'_, Self, Self::Output> 
       where Self::Output: Sized,
             R: Rng + ?Sized { ... }
    fn choose_multiple_array<R, const N: usize>(
        &self,
        rng: &mut R,
    ) -> Option<[Self::Output; N]>
       where Self::Output: Clone + Sized,
             R: Rng + ?Sized { ... }
    fn choose_weighted<R, F, B, X>(
        &self,
        rng: &mut R,
        weight: F,
    ) -> Result<&Self::Output, WeightError>
       where R: Rng + ?Sized,
             F: Fn(&Self::Output) -> B,
             B: SampleBorrow<X>,
             X: SampleUniform + Weight + PartialOrd<X> { ... }
    fn choose_multiple_weighted<R, F, X>(
        &self,
        rng: &mut R,
        amount: usize,
        weight: F,
    ) -> Result<SliceChooseIter<'_, Self, Self::Output>, WeightError>
       where Self::Output: Sized,
             R: Rng + ?Sized,
             F: Fn(&Self::Output) -> X,
             X: Into<f64> { ... }
}
Expand description

Extension trait on indexable lists, providing random sampling methods.

This trait is implemented on [T] slice types. Other types supporting std::ops::Index<usize> may implement this (only Self::len must be specified).

Required Methods§

source

fn len(&self) -> usize

The length

Provided Methods§

source

fn is_empty(&self) -> bool

True when the length is zero

source

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

Uniformly sample one element

Returns a reference to one uniformly-sampled random element of the slice, or None if the slice is empty.

For slices, complexity is O(1).

§Example
use rand::seq::IndexedRandom;

let choices = [1, 2, 4, 8, 16, 32];
let mut rng = rand::rng();
println!("{:?}", choices.choose(&mut rng));
assert_eq!(choices[..0].choose(&mut rng), None);
source

fn choose_multiple<R>( &self, rng: &mut R, amount: usize, ) -> SliceChooseIter<'_, Self, Self::Output>
where Self::Output: Sized, R: Rng + ?Sized,

Uniformly sample amount distinct elements from self

Chooses amount elements from the slice at random, without repetition, and in random order. The returned iterator is appropriate both for collection into a Vec and filling an existing buffer (see example).

In case this API is not sufficiently flexible, use index::sample.

For slices, complexity is the same as index::sample.

§Example
use rand::seq::IndexedRandom;

let mut rng = &mut rand::rng();
let sample = "Hello, audience!".as_bytes();

// collect the results into a vector:
let v: Vec<u8> = sample.choose_multiple(&mut rng, 3).cloned().collect();

// store in a buffer:
let mut buf = [0u8; 5];
for (b, slot) in sample.choose_multiple(&mut rng, buf.len()).zip(buf.iter_mut()) {
    *slot = *b;
}
source

fn choose_multiple_array<R, const N: usize>( &self, rng: &mut R, ) -> Option<[Self::Output; N]>
where Self::Output: Clone + Sized, R: Rng + ?Sized,

Uniformly sample a fixed-size array of distinct elements from self

Chooses N elements from the slice at random, without repetition, and in random order.

For slices, complexity is the same as index::sample_array.

§Example
use rand::seq::IndexedRandom;

let mut rng = &mut rand::rng();
let sample = "Hello, audience!".as_bytes();

let a: [u8; 3] = sample.choose_multiple_array(&mut rng).unwrap();
source

fn choose_weighted<R, F, B, X>( &self, rng: &mut R, weight: F, ) -> Result<&Self::Output, WeightError>
where R: Rng + ?Sized, F: Fn(&Self::Output) -> B, B: SampleBorrow<X>, X: SampleUniform + Weight + PartialOrd<X>,

Biased sampling for one element

Returns a reference to one element of the slice, sampled according to the provided weights. Returns None only if the slice is empty.

The specified function weight maps each item x to a relative likelihood weight(x). The probability of each item being selected is therefore weight(x) / s, where s is the sum of all weight(x).

For slices of length n, complexity is O(n). For more information about the underlying algorithm, see distr::WeightedIndex.

See also choose_weighted_mut.

§Example
use rand::prelude::*;

let choices = [('a', 2), ('b', 1), ('c', 1), ('d', 0)];
let mut rng = rand::rng();
// 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c',
// and 'd' will never be printed
println!("{:?}", choices.choose_weighted(&mut rng, |item| item.1).unwrap().0);
source

fn choose_multiple_weighted<R, F, X>( &self, rng: &mut R, amount: usize, weight: F, ) -> Result<SliceChooseIter<'_, Self, Self::Output>, WeightError>
where Self::Output: Sized, R: Rng + ?Sized, F: Fn(&Self::Output) -> X, X: Into<f64>,

Biased sampling of amount distinct elements

Similar to choose_multiple, but where the likelihood of each element’s inclusion in the output may be specified. The elements are returned in an arbitrary, unspecified order.

The specified function weight maps each item x to a relative likelihood weight(x). The probability of each item being selected is therefore weight(x) / s, where s is the sum of all weight(x).

If all of the weights are equal, even if they are all zero, each element has an equal likelihood of being selected.

This implementation uses O(length + amount) space and O(length) time if the “nightly” feature is enabled, or O(length) space and O(length + amount * log length) time otherwise.

§Known issues

The algorithm currently used to implement this method loses accuracy when small values are used for weights. See #1476.

§Example
use rand::prelude::*;

let choices = [('a', 2), ('b', 1), ('c', 1)];
let mut rng = rand::rng();
// First Draw * Second Draw = total odds
// -----------------------
// (50% * 50%) + (25% * 67%) = 41.7% chance that the output is `['a', 'b']` in some order.
// (50% * 50%) + (25% * 67%) = 41.7% chance that the output is `['a', 'c']` in some order.
// (25% * 33%) + (25% * 33%) = 16.6% chance that the output is `['b', 'c']` in some order.
println!("{:?}", choices.choose_multiple_weighted(&mut rng, 2, |item| item.1).unwrap().collect::<Vec<_>>());

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<T> IndexedRandom for [T]

source§

fn len(&self) -> usize

Implementors§