Created
May 28, 2015 21:02
-
-
Save dudelson/df5cd8c3063e6780a489 to your computer and use it in GitHub Desktop.
Playing around with iterators in rust. See http://hoverbear.org/2015/05/02/a-journey-into-iterators/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(dead_code)] | |
fn double(x: &i32) -> i32{ | |
2*x | |
} | |
fn it_ex_1() { | |
let values: [i32; 3] = [1, 2, 3]; | |
let it = values.iter(); | |
// all of these seem to work | |
// note that the closure doesn't need to take a reference (why??) but the | |
// function does (or else rustc gives us lots of errors) | |
let mapped = it.map(|&x| 2*x); | |
//let mapped = it.map(|x| 2*x); | |
//let mapped = it.map(double); | |
let collected = mapped.collect::<Vec<i32>>(); | |
println!("{:?}", collected); // outputs: [2, 4, 6] | |
} | |
fn it_ex_2() { | |
// all the steps from ex 1 chained together | |
// note that collect doesn't need a type after :: as long as the type of the | |
// binding is explicitly annotated | |
let output: Vec<i32> = [1,2,3].iter().map(|&x| 2*x).collect(); | |
println!("{:?}", output); // outputs: [2, 4, 6] | |
} | |
fn it_ex_3() { | |
// in ex 2 it was possible to call .iter() directly on the array literal | |
// because the array binding did not have to live past that one line | |
// here, however, this does not work because calling .iter() does not actually | |
// move ownership of the array to the Iter struct (iterators are lazy!!) | |
// thus the array itself has to outlive the scope of the iterator (the loop block) | |
// let it = [1,2,3,4,5].iter(); // raises an error | |
let array = [1,2,3,4,5]; | |
let mut it = array.iter(); | |
loop { | |
let n = it.next(); | |
match n { | |
Some(x) => println!("GOT: {}", x), | |
None => break, | |
} | |
} | |
/* outputs: | |
GOT: 1 | |
GOT: 2 | |
GOT: 3 | |
GOT: 4 | |
GOT: 5 | |
*/ | |
} | |
fn it_ex_4() { | |
// a (slightly) more compact version of ex_3 | |
let array = [1,2,3,4,5]; | |
let mut it = array.iter(); | |
let mut n = it.next(); | |
while n.is_some() { | |
println!("GOT: {}", n.unwrap()); | |
n = it.next(); | |
} | |
/* outputs: | |
GOT: 1 | |
GOT: 2 | |
GOT: 3 | |
GOT: 4 | |
GOT: 5 | |
*/ | |
} | |
fn it_ex_5() { | |
// using skip(n) to skip n elements and take(n) to take the next n elements | |
let array = [1,2,3,4,5]; | |
let it = array.iter(); | |
let output: Vec<_> = it.skip(2).take(2).collect(); | |
println!("{:?}", output); // outputs: [3, 4] | |
} | |
fn it_ex_6() { | |
// inspect the iterator pipeline between maps | |
let array = [1,2,3,4,5]; | |
let it = array.iter(); | |
let mapped = it.inspect(|&x| println!("Pre-map: {}", x)) | |
.map(|&x| x*10) | |
.inspect(|&x| println!("First pipe output: {}", x)) | |
.map(|x| x+2) | |
.inspect(|&x| println!("Second pipe output: {}", x)); | |
let collected: Vec<_> = mapped.collect(); | |
println!("This isn't even my final form: {:?}", collected); | |
/* outputs: | |
Pre-map: 1 | |
First pipe output: 10 | |
Second pipe output: 12 | |
Pre-map: 2 | |
First pipe output: 20 | |
Second pipe output: 22 | |
Pre-map: 3 | |
First pipe output: 30 | |
Second pipe output: 32 | |
Pre-map: 4 | |
First pipe output: 40 | |
Second pipe output: 42 | |
Pre-map: 5 | |
First pipe output: 50 | |
Second pipe output: 52 | |
This isn't even my final form: [12, 22, 32, 42, 52] | |
*/ | |
} | |
fn it_ex_7() { | |
let array = [1,2,3]; | |
let cycle = array.iter().cycle(); // an endless iterator over <array> | |
let output: Vec<_> = cycle.take(9).collect(); | |
println!("{:?}", output); // outputs: [1, 2, 3, 1, 2, 3, 1, 2, 3] | |
} | |
fn it_ex_8() { | |
// iteration over a hashmap, collection into a vector | |
use std::collections::HashMap; | |
let mut map = HashMap::new(); | |
map.insert(1, 10); | |
map.insert(2, 20); | |
map.insert(3, 30); | |
let it = map.iter(); | |
let output: Vec<_> = it.map(|(&key, &value)| (key, value*10)).collect(); | |
//let output: Vec<_> = it.collect(); | |
println!("{:?}", output); | |
// outputs: [(1, 100), (3, 300), (2, 200)] on my machine, | |
// but the HashMap implementation makes no guarantees regarding the order of returned | |
// keys/values, so the order of the tuples is indeterministic | |
} | |
fn it_ex_9() { | |
// iterator over a vector, collection into a hashmap | |
use std::collections::HashMap; | |
let vec = vec![(1, 10), (2, 20), (3, 30)]; | |
let it = vec.iter(); | |
let output: HashMap<i32, i32> = it.map(|&t| (t.0, t.1*10)).collect(); | |
//let output: HashMap<_, _> = it.map(|&t| t).collect(); | |
println!("{:?}", output); | |
// outputs: {1: 100, 2: 200, 3: 300} but again, the order of the key/value pairs | |
// is indeterministic | |
} | |
fn main() { | |
it_ex_1(); | |
it_ex_2(); | |
it_ex_3(); | |
it_ex_4(); | |
it_ex_5(); | |
it_ex_6(); | |
it_ex_7(); | |
it_ex_8(); | |
it_ex_9(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment