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. 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<_>>());
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.