Skip to content

Commit 15ddf49

Browse files
committed
added shuflr example
1 parent 1336836 commit 15ddf49

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ in a controlled repository now.
3131
* `deref.rs`: deref trait example
3232
* `from.rs`: from / try_from trait example
3333
* `prog.rs`, `prog2.rs`: state machine examples using closures
34+
* `shuflr/`: iterator implementation example

shuflr/Cargo.toml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "shuflr"
3+
version = "0.1.0"
4+
authors = ["Bart Massey <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
rand = "0.8.3"
11+
12+
[lib]
13+
name = "shuflr"
14+
path = "shuflr.rs"

shuflr/shuflr.rs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use rand::seq::SliceRandom;
2+
use rand::Rng;
3+
4+
pub struct IterShuffled<'a, T> {
5+
values: &'a [T],
6+
indices: Vec<usize>,
7+
}
8+
9+
impl<'a, T> IterShuffled<'a, T> {
10+
pub fn new<R>(values: &'a [T], rng: &mut R) -> Self
11+
where
12+
R: Rng + ?Sized,
13+
{
14+
let nvalues = values.len();
15+
let mut indices: Vec<usize> = (0..nvalues).collect();
16+
indices.shuffle(rng);
17+
IterShuffled { values, indices }
18+
}
19+
}
20+
21+
impl<'a, T> Iterator for IterShuffled<'a, T> {
22+
type Item = &'a T;
23+
fn next(&mut self) -> Option<Self::Item> {
24+
self.indices.pop().map(|i| &self.values[i])
25+
}
26+
}
27+
28+
pub trait Shuffled<T> {
29+
fn shuffled<R>(&self, rng: &mut R) -> IterShuffled<T>
30+
where
31+
R: Rng + ?Sized;
32+
}
33+
34+
impl<T> Shuffled<T> for [T] {
35+
fn shuffled<R>(&self, rng: &mut R) -> IterShuffled<T>
36+
where
37+
R: Rng + ?Sized,
38+
{
39+
IterShuffled::new(self, rng)
40+
}
41+
}
42+
43+
#[test]
44+
pub fn test_shuffled() {
45+
let mut rng = rand::thread_rng();
46+
let vals = &['a', 'b', 'c'];
47+
let mut v = Vec::new();
48+
for &c in vals.shuffled(&mut rng) {
49+
v.push(c);
50+
}
51+
v.sort();
52+
assert_eq!(&v, vals);
53+
}

0 commit comments

Comments
 (0)