pub trait SliceRandom {
type Item;
// Required methods
fn choose<R>(&self, rng: &mut R) -> Option<&Self::Item>
where R: Rng + ?Sized;
fn choose_mut<R>(&mut self, rng: &mut R) -> Option<&mut Self::Item>
where R: Rng + ?Sized;
fn choose_multiple<R>(
&self,
rng: &mut R,
amount: usize,
) -> SliceChooseIter<'_, Self, Self::Item> ⓘ
where R: Rng + ?Sized;
fn choose_weighted<R, F, B, X>(
&self,
rng: &mut R,
weight: F,
) -> Result<&Self::Item, WeightedError>
where R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default;
fn choose_weighted_mut<R, F, B, X>(
&mut self,
rng: &mut R,
weight: F,
) -> Result<&mut Self::Item, WeightedError>
where R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default;
fn choose_multiple_weighted<R, F, X>(
&self,
rng: &mut R,
amount: usize,
weight: F,
) -> Result<SliceChooseIter<'_, Self, Self::Item>, WeightedError>
where R: Rng + ?Sized,
F: Fn(&Self::Item) -> X,
X: Into<f64>;
fn shuffle<R>(&mut self, rng: &mut R)
where R: Rng + ?Sized;
fn partial_shuffle<R>(
&mut self,
rng: &mut R,
amount: usize,
) -> (&mut [Self::Item], &mut [Self::Item])
where R: Rng + ?Sized;
}
Expand description
Extension trait on slices, providing random mutation and sampling methods.
This trait is implemented on all [T]
slice types, providing several
methods for choosing and shuffling elements. You must use
this trait:
use rand::seq::SliceRandom;
let mut rng = rand::thread_rng();
let mut bytes = "Hello, random!".to_string().into_bytes();
bytes.shuffle(&mut rng);
let str = String::from_utf8(bytes).unwrap();
println!("{}", str);
Example output (non-deterministic):
l,nmroHado !le
Required Associated Types§
Required Methods§
sourcefn choose<R>(&self, rng: &mut R) -> Option<&Self::Item>
fn choose<R>(&self, rng: &mut R) -> Option<&Self::Item>
Returns a reference to one random element of the slice, or None
if the
slice is empty.
For slices, complexity is O(1)
.
§Example
use rand::thread_rng;
use rand::seq::SliceRandom;
let choices = [1, 2, 4, 8, 16, 32];
let mut rng = thread_rng();
println!("{:?}", choices.choose(&mut rng));
assert_eq!(choices[..0].choose(&mut rng), None);
sourcefn choose_mut<R>(&mut self, rng: &mut R) -> Option<&mut Self::Item>
fn choose_mut<R>(&mut self, rng: &mut R) -> Option<&mut Self::Item>
Returns a mutable reference to one random element of the slice, or
None
if the slice is empty.
For slices, complexity is O(1)
.
sourcefn choose_multiple<R>(
&self,
rng: &mut R,
amount: usize,
) -> SliceChooseIter<'_, Self, Self::Item> ⓘ
Available on crate feature alloc
only.
fn choose_multiple<R>( &self, rng: &mut R, amount: usize, ) -> SliceChooseIter<'_, Self, Self::Item> ⓘ
alloc
only.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::SliceRandom;
let mut rng = &mut rand::thread_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_weighted<R, F, B, X>(
&self,
rng: &mut R,
weight: F,
) -> Result<&Self::Item, WeightedError>where
R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default,
Available on crate feature alloc
only.
fn choose_weighted<R, F, B, X>(
&self,
rng: &mut R,
weight: F,
) -> Result<&Self::Item, WeightedError>where
R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default,
alloc
only.Similar to choose
, but where the likelihood of each outcome may be
specified.
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)
.
See also choose_weighted_mut
, distributions::weighted
.
§Example
use rand::prelude::*;
let choices = [('a', 2), ('b', 1), ('c', 1)];
let mut rng = thread_rng();
// 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
println!("{:?}", choices.choose_weighted(&mut rng, |item| item.1).unwrap().0);
sourcefn choose_weighted_mut<R, F, B, X>(
&mut self,
rng: &mut R,
weight: F,
) -> Result<&mut Self::Item, WeightedError>where
R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default,
Available on crate feature alloc
only.
fn choose_weighted_mut<R, F, B, X>(
&mut self,
rng: &mut R,
weight: F,
) -> Result<&mut Self::Item, WeightedError>where
R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default,
alloc
only.Similar to choose_mut
, but where the likelihood of each outcome may
be specified.
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)
.
See also choose_weighted
, distributions::weighted
.
sourcefn choose_multiple_weighted<R, F, X>(
&self,
rng: &mut R,
amount: usize,
weight: F,
) -> Result<SliceChooseIter<'_, Self, Self::Item>, WeightedError>
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::Item>, WeightedError>
std
only.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.
The complexity of this method depends on the feature partition_at_index
.
If the feature is enabled, then for slices of length n
, the complexity
is O(n)
space and O(n)
time. Otherwise, the complexity is O(n)
space and
O(n * log amount)
time.
§Example
use rand::prelude::*;
let choices = [('a', 2), ('b', 1), ('c', 1)];
let mut rng = thread_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<_>>());
sourcefn shuffle<R>(&mut self, rng: &mut R)
fn shuffle<R>(&mut self, rng: &mut R)
Shuffle a mutable slice in place.
For slices of length n
, complexity is O(n)
.
§Example
use rand::seq::SliceRandom;
use rand::thread_rng;
let mut rng = thread_rng();
let mut y = [1, 2, 3, 4, 5];
println!("Unshuffled: {:?}", y);
y.shuffle(&mut rng);
println!("Shuffled: {:?}", y);
sourcefn partial_shuffle<R>(
&mut self,
rng: &mut R,
amount: usize,
) -> (&mut [Self::Item], &mut [Self::Item])
fn partial_shuffle<R>( &mut self, rng: &mut R, amount: usize, ) -> (&mut [Self::Item], &mut [Self::Item])
Shuffle a slice in place, but exit early.
Returns two mutable slices from the source slice. The first contains
amount
elements randomly permuted. The second has the remaining
elements that are not fully shuffled.
This is an efficient method to select amount
elements at random from
the slice, provided the slice may be mutated.
If you only need to choose elements randomly and amount > self.len()/2
then you may improve performance by taking
amount = values.len() - amount
and using only the second slice.
If amount
is greater than the number of elements in the slice, this
will perform a full shuffle.
For slices, complexity is O(m)
where m = amount
.
Object Safety§
Implementations on Foreign Types§
source§impl<T> SliceRandom for [T]
impl<T> SliceRandom for [T]
type Item = T
fn choose<R>(&self, rng: &mut R) -> Option<&Self::Item>
fn choose_mut<R>(&mut self, rng: &mut R) -> Option<&mut Self::Item>
source§fn choose_multiple<R>(
&self,
rng: &mut R,
amount: usize,
) -> SliceChooseIter<'_, Self, Self::Item> ⓘ
fn choose_multiple<R>( &self, rng: &mut R, amount: usize, ) -> SliceChooseIter<'_, Self, Self::Item> ⓘ
alloc
only.source§fn choose_weighted<R, F, B, X>(
&self,
rng: &mut R,
weight: F,
) -> Result<&Self::Item, WeightedError>where
R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default,
fn choose_weighted<R, F, B, X>(
&self,
rng: &mut R,
weight: F,
) -> Result<&Self::Item, WeightedError>where
R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default,
alloc
only.source§fn choose_weighted_mut<R, F, B, X>(
&mut self,
rng: &mut R,
weight: F,
) -> Result<&mut Self::Item, WeightedError>where
R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default,
fn choose_weighted_mut<R, F, B, X>(
&mut self,
rng: &mut R,
weight: F,
) -> Result<&mut Self::Item, WeightedError>where
R: Rng + ?Sized,
F: Fn(&Self::Item) -> B,
B: SampleBorrow<X>,
X: SampleUniform + for<'a> AddAssign<&'a X> + PartialOrd<X> + Clone + Default,
alloc
only.source§fn choose_multiple_weighted<R, F, X>(
&self,
rng: &mut R,
amount: usize,
weight: F,
) -> Result<SliceChooseIter<'_, Self, Self::Item>, WeightedError>
fn choose_multiple_weighted<R, F, X>( &self, rng: &mut R, amount: usize, weight: F, ) -> Result<SliceChooseIter<'_, Self, Self::Item>, WeightedError>
std
only.