add iterators for list
This commit is contained in:
parent
1e4049204e
commit
2291b4bf73
@ -1,11 +1,13 @@
|
||||
use std::fmt;
|
||||
use std::option::Option;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LinkedList<T> {
|
||||
head: Option<Box<Node<T>>>,
|
||||
size: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Node<T> {
|
||||
value: T,
|
||||
next: Option<Box<Node<T>>>,
|
||||
@ -43,7 +45,9 @@ impl<T> LinkedList<T> {
|
||||
Some(node.value)
|
||||
}
|
||||
|
||||
|
||||
pub fn iter<'a>(&'a self) -> LinkedListIter<'a, T> {
|
||||
LinkedListIter { item: &self.head }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -110,3 +114,56 @@ impl<T:PartialEq> PartialEq for LinkedList<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LinkedListIter<'a, T> {
|
||||
item: &'a Option<Box<Node<T>>>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for LinkedListIter<'a, T> {
|
||||
type Item = &'a T;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.item {
|
||||
Some(node) => {
|
||||
self.item = &node.next;
|
||||
Some(&node.value)
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoIterator for &'a LinkedList<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = LinkedListIter<'a, T>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
LinkedListIter {item: &self.head}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IntoIter<T>(LinkedList<T>);
|
||||
|
||||
impl<T> Iterator for IntoIter<T> {
|
||||
type Item = T;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.0.pop_front()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoIterator for LinkedList<T> {
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
IntoIter(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ComputeNorm {
|
||||
fn compute_norm(&self) -> f64 {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeNorm for LinkedList<f64> {
|
||||
fn compute_norm(&self) -> f64 {
|
||||
self.iter().map(|x| {x * x}).sum::<f64>().sqrt()
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,14 @@
|
||||
use linked_list::LinkedList;
|
||||
|
||||
use crate::linked_list::ComputeNorm;
|
||||
pub mod linked_list;
|
||||
|
||||
fn main() {
|
||||
let mut list: LinkedList<u32> = LinkedList::new();
|
||||
let mut list: LinkedList<String> = LinkedList::new();
|
||||
assert!(list.is_empty());
|
||||
assert_eq!(list.get_size(), 0);
|
||||
for i in 1..12 {
|
||||
list.push_front(i);
|
||||
list.push_front(i.to_string());
|
||||
}
|
||||
println!("{}", list);
|
||||
println!("list size: {}", list.get_size());
|
||||
@ -22,7 +24,22 @@ fn main() {
|
||||
println!("list == list2 ?= {}", list == list2);
|
||||
|
||||
// If you implement iterator trait:
|
||||
//for val in &list {
|
||||
// println!("{}", val);
|
||||
//}
|
||||
for val in &list {
|
||||
// reference iterator
|
||||
print!("{} ", val);
|
||||
}
|
||||
println!();
|
||||
for val in list {
|
||||
// consuming iterator
|
||||
print!("{} ", val);
|
||||
}
|
||||
println!();
|
||||
// let mut error = list.into_iter();
|
||||
// list 's moved in the second loop, so it cannot be used again
|
||||
// assert_eq!(Some(String::from("10")), error.next());
|
||||
let mut list: LinkedList<f64> = LinkedList::new();
|
||||
for i in 1..12 {
|
||||
list.push_front(f64::from(i));
|
||||
}
|
||||
println!("ComputeNorm for {:?} = {}", list, list.compute_norm());
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user