pub fn apply<F>(
        &self,
        other: &TimeSeries<'a, T>,
        func: F,
    ) -> Result<TimeSeries<'a, T>, TimeSeriesError>
    where
        F: FnMut((&T, &T)) -> T,
        T: Copy,
    {
        if self.timeline != other.timeline {
            return Err(TimeSeriesError::TimelinesDoNotMatch);
        }
        let data = self
            .values
            .iter()
            .zip(other.values.iter())
            .map(func)
            .collect();
        let ts = TimeSeries::new(self.timeline, data)?;
        Ok(ts)
    }
/// Allows the user to provide a closure that defines the pairwise combination
/// of two time series
///
/// Note that for simple artihmetic operations (+, -, *, /) these operators are already
/// directly defined for the TimeSeries object, so that as long as you can apply the
/// arithmetic operation on the underlying value type (e.g. you can't divide Strings)
/// then you will be able to write something like this: `ts3 = &ts1 + &ts2;` or
/// `ts3 = &ts1 + 10;`
///
/// The closure cannot have side effects (i.e. change the inputs provided). This
/// is to ensure that the `TimeSeries` being operated on, don't change in the process
/// of generating a new `TimeSeries`
///
/// ---
/// ### Example
/// ```
/// use timeseries::{TimeSeries, Timeline, DateRange, Period, Duration};
/// use time::{Date, Month};
///
/// // Create a timeline
/// let from = Date::from_calendar_date(2022, Month::January, 10).unwrap();
/// let to = Date::from_calendar_date(2023, Month::January, 10).unwrap();
/// let dr = DateRange::new(from, to);
/// let tl = Timeline::new(dr, Period::Quarter);
///
/// // Create two timeseries
/// let v1 = vec![1, 2, 3, 4];
/// let ts1 = TimeSeries::new(&tl, v1).unwrap();
/// let v2 = vec![5, 6, 7, 8];
/// let ts2 = TimeSeries::new(&tl, v2).unwrap();
///
/// // Write a generic function that can be pairwise applied to the elements of a TS and apply it
/// let op = |(&a, &b): (&i32, &i32)| -> i32 {
///     if a < 3 {
///         1
///     } else {
///         b + 1
///     }
/// };
/// let ts3 = ts1.apply(&ts2, op).unwrap();
/// assert_eq!(ts3.value_range(dr).unwrap(), vec![1, 1, 8, 9]);
///
/// ```
Allows the user to provide a closure that defines the pairwise combination
of two time series

Note that for simple artihmetic operations (+, -, *, /) these operators are already
directly defined for the TimeSeries object, so that as long as you can apply the
arithmetic operation on the underlying value type
then you will be able to write something like this: `ts3 = &ts1 + &ts2` or
`ts3 = &ts1 + 10;`

The closure cannot have side effects . This
is to ensure that the `TimeSeries` being operated on, don't change in the process
of generating a new `TimeSeries`
Allows the user to provide a closure that defines the pairwise combination of two time series Note that for simple artihmetic operations ( + - * / ) these operators are already directly defined for the TimeSeries object so that as long as you can apply the arithmetic operation on the underlying value type then you will be able to write something like this : ` ts3 = &ts1 + &ts2 ` or ` ts3 = &ts1 + 10 ; ` The closure cannot have side effects . This is to ensure that the ` TimeSeries ` being operated on don ' t change in the process of generating a new ` TimeSeries `
pub fn apply<F>(
        &self,
        other: &TimeSeries<'a, T>,
        func: F,
    ) -> Result<TimeSeries<'a, T>, TimeSeriesError>
    where
        F: FnMut((&T, &T)) -> T,
        T: Copy,
    {
        if self.timeline != other.timeline {
            return Err(TimeSeriesError::TimelinesDoNotMatch);
        }
        let data = self
            .values
            .iter()
            .zip(other.values.iter())
            .map(func)
            .collect();
        let ts = TimeSeries::new(self.timeline, data)?;
        Ok(ts)
    }
pub fn apply < F > ( & self , other : & TimeSeries < ' a , T > , func : F , ) -> Result < TimeSeries < ' a , T > , TimeSeriesError > where F : FnMut ( ( & T , & T ) ) -> T , T : Copy , { if self . timeline != other . timeline { return Err ( TimeSeriesError :: TimelinesDoNotMatch ) ; } let data = self . values . iter ( ) . zip ( other . values . iter ( ) ) . map ( func ) . collect ( ) ; let ts = TimeSeries :: new ( self . timeline , data ) ? ; Ok ( ts ) }
Allows the user to provide a closure that defines the pairwise combination
of two time series
Allows the user to provide a closure that defines the pairwise combination of two time series
&self
other
&TimeSeries<'a, T>
func
F
&self
other
&TimeSeries<'a, T>
func
F
example
```
use timeseries::{TimeSeries, Timeline, DateRange, Period, Duration};
use time::{Date, Month}.

Create a timeline
let from = Date::from_calendar_date(2022, Month::January, 10).unwrap();
let to = Date::from_calendar_date(2023, Month::January, 10).unwrap();
let dr = DateRange::new(from, to);
let tl = Timeline::new(dr, Period::Quarter).



Write a generic function that can be pairwise applied to the elements of a TS and apply it
let op = |(&a, &b): (&i32, &i32)| -> i32 {
if a < 3 {
1
} else {
b + 1
}
};
let ts3 = ts1.apply(&ts2, op).unwrap();
assert_eq!(ts3.value_range(dr).unwrap(), vec![1, 1, 8, 9]).


` ` ` use timeseries :: { TimeSeries Timeline DateRange Period Duration } ; use time :: { Date Month } . Create a timeline let from = Date :: from_calendar_date ( 2022 Month :: January 10 ) . unwrap () ; let to = Date :: from_calendar_date ( 2023 Month :: January 10 ) . unwrap () ; let dr = DateRange :: new ( from to ) ; let tl = Timeline :: new ( dr Period :: Quarter ) . Write a generic function that can be pairwise applied to the elements of a TS and apply it let op = | ( &a &b ) : ( &i32 &i32 ) | - > i32 { if a < 3 { 1 } else { b + 1 } } ; let ts3 = ts1 . apply ( &ts2 op ) . unwrap () ; assert_eq! ( ts3 . value_range ( dr ) . unwrap () vec! [ 1 1 8 9 ] ) .