I have some vectors consisting on TimeValue tuples ie type TimeValue = (DateTime, f64);
Now I want to add these types of vectors together. However, the datetime values have to match between vectors . For example data like below. Missing data has to be ignored.
let d1 = Utc.ymd(2019, 12, 9).and_hms(1, 1, 0);
let d2 = Utc.ymd(2019, 12, 9).and_hms(1, 2, 0);
let d3 = Utc.ymd(2019, 12, 9).and_hms(1, 3, 0);
let d4 = Utc.ymd(2019, 12, 9).and_hms(1, 4, 0);
let d5 = Utc.ymd(2019, 12, 9).and_hms(1, 5, 0);
let d6 = Utc.ymd(2019, 12, 9).and_hms(1, 6, 0);
let d7 = Utc.ymd(2019, 12, 9).and_hms(1, 7, 0);
let lhs_values = vec![(d1, 1.0), (d3, 3.0), (d4, 4.0), (d5, 5.0), (d6, 6.0)];
let rhs_values = vec![(d1, 1.0), (d2, 2.0), (d3, 3.0), (d5, 5.0), (d6, 6.0), (d7, 7.0)];
The following code seems to work. (truncate is a custom method. Just assume datetimes are truncated to the minute say)
let mut it_lhs = lhs_values.iter();
let mut it_rhs = rhs_values.iter();
let mut it_lhs_value = it_lhs.next();
let mut it_rhs_value = it_rhs.next();
loop {
match (it_lhs_value, it_rhs_value) {
(Some(lhs_row), Some(rhs_row)) => {
let lhs_dt: DateTime<Utc> = lhs_row.0.truncate(chrono::Duration::minutes(1));
let rhs_dt: DateTime<Utc> = rhs_row.0.truncate(chrono::Duration::minutes(1));
if lhs_dt > rhs_dt {
it_rhs_value = it_rhs.next();
continue;
}
else if rhs_dt > lhs_dt {
it_lhs_value = it_lhs.next();
continue;
}
else {
// Do what I need here as the datetimes match for the pair
it_rhs_value = it_rhs.next();
it_lhs_value = it_lhs.next();
}
},
(Some(lhs_row), None) => {
it_lhs_value = it_lhs.next();
continue
},
(None, Some(rhs_row)) => {
it_rhs_value = it_rhs.next();
continue
},
(None, None) => break,
}
}
This is not that elegant though. I thought I may be able to create my own iterator that does this for me like zip. The zip code zip.rs - source is quite complicated though . How can I define an iterator that takes two iterators of TimeValue values ?
So far I have
pub struct TimeValueZip<A> {
a: A,
b: A
}
impl<A: Iterator,> TimeValueZip<A> {
pub fn new(a: A, b: A) -> TimeValueZip<A> {
TimeValueZip{
a: a,
b: b
}
}
}
impl<A> Iterator for TimeValueZip<A> where A: Iterator
{
type Item = (A::Item, A::Item);
// Here, we define the sequence using `.curr` and `.next`.
// The return type is `Option<T>`:
// * When the `Iterator` is finished, `None` is returned.
// * Otherwise, the next value is wrapped in `Some` and returned.
fn next(&mut self) -> Option<Self::Item> {
}
}
How do I specify that the iterators have to be iterators to TimeValues ?
Thanks