Skip to content

Instantly share code, notes, and snippets.

@nvzqz
Last active December 1, 2017 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nvzqz/49c32c8585108afae51e9642c6872f68 to your computer and use it in GitHub Desktop.
Save nvzqz/49c32c8585108afae51e9642c6872f68 to your computer and use it in GitHub Desktop.
`Choose` trait for rand crate
#![feature(specialization)]
extern crate rand;
use rand::Rng;
trait Choose {
type Item;
fn choose<R: Rng>(self, rng: &mut R) -> Option<Self::Item>;
}
impl<T: IntoIterator> Choose for T {
type Item = <T as IntoIterator>::Item;
default fn choose<R: Rng>(self, rng: &mut R) -> Option<T::Item> {
let mut value = None;
for (i, elem) in self.into_iter().enumerate() {
if i == 0 || rng.gen_range(0, i + 1) == 0 {
value = Some(elem);
}
}
value
}
}
impl<'a, T> Choose for &'a [T] {
fn choose<R: Rng>(self, rng: &mut R) -> Option<&'a T> {
if self.is_empty() {
None
} else {
Some(&self[rng.gen_range(0, self.len())])
}
}
}
impl<'a, T> Choose for &'a mut [T] {
fn choose<R: Rng>(self, rng: &mut R) -> Option<&'a mut T> {
if self.is_empty() {
None
} else {
let len = self.len();
Some(&mut self[rng.gen_range(0, len)])
}
}
}
fn main() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment