use std::cmp::Ordering;
use std::iter::Peekable;
pub struct SortedIter<I, E, F>
where
I: Iterator,
E: Ord,
F: Fn(&I::Item) -> E,
{
a: Peekable<I>,
b: Peekable<I>,
cmp: F,
size: usize,
counter: usize,
}
impl<I, E, F> Iterator for SortedIter<I, E, F>
where
I: Iterator,
E: Ord,
F: Fn(&I::Item) -> E,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
if self.counter == self.size {
return None;
} else {
self.counter += 1;
}
let a_next = self.a.peek();
let b_next = self.b.peek();
match (a_next, b_next) {
(Some(a), Some(b)) => match (self.cmp)(a).cmp(&(self.cmp)(b)) {
Ordering::Less => self.a.next(),
Ordering::Equal => {
self.b.next();
self.a.next()
}
Ordering::Greater => self.b.next(),
},
(Some(_), None) => self.a.next(),
(None, Some(_)) => self.b.next(),
(None, None) => None,
}
}
}
pub fn sorted_iter<I, E, F>(a: I, b: I, cmp: F, size: usize) -> SortedIter<I, E, F>
where
I: Iterator,
E: Ord,
F: Fn(&I::Item) -> E,
{
SortedIter {
a: a.peekable(),
b: b.peekable(),
cmp,
size,
counter: 0,
}
}
#[test]
fn test_sorted_iter() {
let a: Vec<i32> = Vec::new();
let b: Vec<i32> = Vec::new();
let len = 1;
let cmp = |x: &i32| *x;
let s = sorted_iter(a.into_iter(), b.into_iter(), cmp, len);
let result: Vec<i32> = s.collect();
assert_eq!(result, Vec::<i32>::new());
let a = vec![1];
let b: Vec<i32> = Vec::new();
let len = 1;
let cmp = |x: &i32| *x;
let iter = sorted_iter(a.into_iter(), b.into_iter(), cmp, len);
let result: Vec<i32> = iter.collect();
assert_eq!(result, vec![1]);
let a: Vec<i32> = Vec::new();
let b = vec![1];
let len = 1;
let cmp = |x: &i32| *x;
let iter = sorted_iter(a.into_iter(), b.into_iter(), cmp, len);
let result: Vec<i32> = iter.collect();
assert_eq!(result, vec![1]);
let a = vec![1, 2];
let b = vec![3, 4];
let len = 4;
let cmp = |x: &i32| *x;
let iter = sorted_iter(a.into_iter(), b.into_iter(), cmp, len);
let result: Vec<i32> = iter.collect();
assert_eq!(result, vec![1, 2, 3, 4]);
let a = vec![1, 2, 3, 4, 5, 6];
let b = vec![4, 5, 6, 7, 8, 9, 10];
let len = 10;
let cmp = |x: &i32| *x;
let iter = sorted_iter(a.into_iter(), b.into_iter(), cmp, len);
let result: Vec<i32> = iter.collect();
assert_eq!(result, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
let a = vec![(1, 1), (2, 1), (3, 1)];
let b = vec![(1, 2), (2, 2), (4, 2)];
let len = 4;
let cmp = |x: &(i32, i32)| x.0;
let iter = sorted_iter(a.into_iter(), b.into_iter(), cmp, len);
let result: Vec<(i32, i32)> = iter.collect();
assert_eq!(result, vec![(1, 1), (2, 1), (3, 1), (4, 2)]);
let a = vec![(1, None), (2, None), (3, Some(1))];
let b = vec![(1, Some(2)), (2, Some(2)), (4, Some(2))];
let len = 4;
let cmp = |x: &(i32, Option<i32>)| x.0;
let iter = sorted_iter(a.into_iter(), b.into_iter(), cmp, len);
let result: Vec<(i32, Option<i32>)> = iter.collect();
assert_eq!(
result,
vec![(1, None), (2, None), (3, Some(1)), (4, Some(2))]
);
}