add iterators for list
This commit is contained in:
parent
1e4049204e
commit
2291b4bf73
@ -1,11 +1,13 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::option::Option;
|
use std::option::Option;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct LinkedList<T> {
|
pub struct LinkedList<T> {
|
||||||
head: Option<Box<Node<T>>>,
|
head: Option<Box<Node<T>>>,
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct Node<T> {
|
struct Node<T> {
|
||||||
value: T,
|
value: T,
|
||||||
next: Option<Box<Node<T>>>,
|
next: Option<Box<Node<T>>>,
|
||||||
@ -43,7 +45,9 @@ impl<T> LinkedList<T> {
|
|||||||
Some(node.value)
|
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 linked_list::LinkedList;
|
||||||
|
|
||||||
|
use crate::linked_list::ComputeNorm;
|
||||||
pub mod linked_list;
|
pub mod linked_list;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut list: LinkedList<u32> = LinkedList::new();
|
let mut list: LinkedList<String> = LinkedList::new();
|
||||||
assert!(list.is_empty());
|
assert!(list.is_empty());
|
||||||
assert_eq!(list.get_size(), 0);
|
assert_eq!(list.get_size(), 0);
|
||||||
for i in 1..12 {
|
for i in 1..12 {
|
||||||
list.push_front(i);
|
list.push_front(i.to_string());
|
||||||
}
|
}
|
||||||
println!("{}", list);
|
println!("{}", list);
|
||||||
println!("list size: {}", list.get_size());
|
println!("list size: {}", list.get_size());
|
||||||
@ -20,9 +22,24 @@ fn main() {
|
|||||||
list2.pop_front();
|
list2.pop_front();
|
||||||
println!("list2.pop_front: {}", list2);
|
println!("list2.pop_front: {}", list2);
|
||||||
println!("list == list2 ?= {}", list == list2);
|
println!("list == list2 ?= {}", list == list2);
|
||||||
|
|
||||||
// If you implement iterator trait:
|
// If you implement iterator trait:
|
||||||
//for val in &list {
|
for val in &list {
|
||||||
// println!("{}", val);
|
// 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