I'm trying to generate all combinations of a date range using Rust itertools but it says that trait bounds were not satisfied.
extern crate chrono;
extern crate itertools;
use itertools::Itertools;
use chrono::prelude::*;
fn main() {
let min = NaiveDate::from_ymd(2018, 10, 1);
let max = NaiveDate::from_ymd(2018, 10, 14);
let combinations = (min..=max).combinations(5);
}
The error message:
error[E0599]: no method named `combinations` found for type `std::ops::RangeInclusive<chrono::NaiveDate>` in the current scope
--> src/main.rs:46:36
|
46 | let combinations = (min..=max).combinations(5);
| ^^^^^^^^^^^^
|
= note: the method `combinations` exists but the following trait bounds were not satisfied:
`std::ops::RangeInclusive<chrono::NaiveDate> : itertools::Itertools`
`&std::ops::RangeInclusive<chrono::NaiveDate> : itertools::Itertools`
`&mut std::ops::RangeInclusive<chrono::NaiveDate> : itertools::Itertools`
I would expect that Itertools
were implemented for generic RangeInclusive
. I am learning Rust so I might be missing something obvious.
The itertools. combinations() function takes two arguments—an iterable inputs and a positive integer n —and produces an iterator over tuples of all combinations of n elements in inputs .
What does itertools. combinations() do ? It returns r length subsequences of elements from the input iterable. Combinations are emitted in lexicographic sort order.
To create combinations without using itertools, iterate the list one by one and fix the first element of the list and make combinations with the remaining list. Similarly, iterate with all the list elements one by one by recursion of the remaining list.
Itertools, as the name suggests, works on Iterator
s. It is not possible to create an iterable range of a type from outside of the standard library in stable Rust (version 1.29).
Instead, we can create a custom iterator for a date range, based on looping over dates
extern crate chrono; // 0.4.6
extern crate itertools; // 0.7.8
use chrono::{Duration, NaiveDate};
use itertools::Itertools;
use std::mem;
struct DateRange(NaiveDate, NaiveDate);
impl Iterator for DateRange {
type Item = NaiveDate;
fn next(&mut self) -> Option<Self::Item> {
if self.0 < self.1 {
let next = self.0 + Duration::days(1);
Some(mem::replace(&mut self.0, next))
} else {
None
}
}
}
fn main() {
let min = NaiveDate::from_ymd(2018, 10, 1);
let max = NaiveDate::from_ymd(2018, 10, 14);
let combinations: Vec<_> = DateRange(min, max).combinations(5).collect();
println!("{:?}", combinations)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With