File tree 3 files changed +68
-0
lines changed
3 files changed +68
-0
lines changed Original file line number Diff line number Diff line change @@ -31,3 +31,4 @@ in a controlled repository now.
31
31
* ` deref.rs ` : deref trait example
32
32
* ` from.rs ` : from / try_from trait example
33
33
* ` prog.rs ` , ` prog2.rs ` : state machine examples using closures
34
+ * ` shuflr/ ` : iterator implementation example
Original file line number Diff line number Diff line change
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"
Original file line number Diff line number Diff line change
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
+ }
You can’t perform that action at this time.
0 commit comments