Skip to content

Commit 7f84572

Browse files
committed
Add Rng::pick method
Acts similarly to choose, except it is generic over all T: IntoIterator.
1 parent 821acdf commit 7f84572

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,36 @@ pub trait Rng {
534534
AsciiGenerator { rng: self }
535535
}
536536

537+
/// Return a random element from `iter`, or `None` if `iter` is empty.
538+
///
539+
/// When dealing with slices, use [`choose`](#method.choose) or
540+
/// [`choose_mut`](#method.choose_mut) for more efficient solutions.
541+
///
542+
/// # Example
543+
///
544+
/// ```rust
545+
/// use rand::{thread_rng, Rng};
546+
///
547+
/// let choices = [1, 1, 2, 3, 5, 8];
548+
/// let mut rng = thread_rng();
549+
///
550+
/// let iter = choices.iter()
551+
/// .rev()
552+
/// .map(|x| x * 3)
553+
/// .take(2);
554+
///
555+
/// assert!(rng.pick(iter).unwrap() >= 15);
556+
/// ```
557+
fn pick<I: IntoIterator>(&mut self, iter: I) -> Option<I::Item> where Self: Sized {
558+
let mut value = None;
559+
for (i, elem) in iter.into_iter().enumerate() {
560+
if i == 0 || self.gen_range(0, i + 1) == 0 {
561+
value = Some(elem);
562+
}
563+
}
564+
value
565+
}
566+
537567
/// Return a random element from `values`.
538568
///
539569
/// Return `None` if `values` is empty.

0 commit comments

Comments
 (0)