add iterators for list

This commit is contained in:
ridethepig 2023-02-26 16:28:39 +00:00
parent 1e4049204e
commit 2291b4bf73
2 changed files with 81 additions and 7 deletions

View File

@ -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()
}
}

View File

@ -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());
@ -20,9 +22,24 @@ fn main() {
list2.pop_front();
println!("list2.pop_front: {}", list2);
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());
}