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§
Provided Methods§
Sourcefn choose<R>(&self, rng: &mut R) -> Option<&Self::Output>
fn choose<R>(&self, rng: &mut R) -> Option<&Self::Output>
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);
Sourcefn choose_multiple<R>(
&self,
rng: &mut R,
amount: usize,
) -> SliceChooseIter<'_, Self, Self::Output> ⓘ
Available on crate feature alloc
only.
fn choose_multiple<R>( &self, rng: &mut R, amount: usize, ) -> SliceChooseIter<'_, Self, Self::Output> ⓘ
alloc
only.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;
}
Sourcefn choose_multiple_array<R, const N: usize>(
&self,
rng: &mut R,
) -> Option<[Self::Output; N]>
fn choose_multiple_array<R, const N: usize>( &self, rng: &mut R, ) -> Option<[Self::Output; N]>
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();
Sourcefn 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>,
Available on crate feature alloc
only.
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>,
alloc
only.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 the WeightedIndex
distribution.
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);
Sourcefn choose_multiple_weighted<R, F, X>(
&self,
rng: &mut R,
amount: usize,
weight: F,
) -> Result<SliceChooseIter<'_, Self, Self::Output>, WeightError>
Available on crate feature std
only.
fn choose_multiple_weighted<R, F, X>( &self, rng: &mut R, amount: usize, weight: F, ) -> Result<SliceChooseIter<'_, Self, Self::Output>, WeightError>
std
only.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. Zero-weighted
elements are never returned; the result may therefore contain fewer
elements than amount
even when self.len() >= amount
. 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)
.
This implementation uses O(length + amount)
space and O(length)
time.
See index::sample_weighted
for details.
§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<_>>());
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.