Skip to content

Instantly share code, notes, and snippets.

@dudelson
Created May 28, 2015 21:02
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 dudelson/df5cd8c3063e6780a489 to your computer and use it in GitHub Desktop.
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/
#![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