如何使用Itertools创建一系列Chrono日期的所有组合?

时间:2018-10-10 06:11:17

标签: rust

我正在尝试使用Rust itertools生成日期范围的所有组合,但是它表示不满足特征范围。

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);
}

错误消息:

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`

我希望为通用Itertools实现RangeInclusive。我正在学习Rust,所以我可能会遗漏一些明显的东西。

1 个答案:

答案 0 :(得分:2)

顾名思义,

Itertools可在 Iterator s 上运行。 not possible是在稳定的Rust(版本1.29)中从标准库之外创建类型的可迭代范围。

相反,我们可以基于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)
}