如何在未知大小的Vec <Vec <T >>上创建迭代器,该迭代器等效于内部Vec <T>上的迭代器的笛卡尔积?

时间:2019-08-16 00:25:36

标签: rust iterator generator

我想设计一个与示例here类似的函数,除了在我的情况下,iproduct的参数数量在编译时未知。如here所述,这很容易在python中完成。

我尝试使用itertools板条箱,尤其是iproduct!multi_cartesian_productcartesian_product,但目前正在使用类型系统,并且不确定是否正确路径。

pub fn product_of_lists(lists: &Vec<Vec<u16>>) -> std::slice::Iter<'_, u16> {
    // generate cross products between lists
    assert!(lists.len() > 2);
    let mut product_iter = lists[0].iter();
    for (en, list) in lists.iter().enumerate() {
        if en > 0{
            product_iter = iproduct!(product_iter, list.iter());
        }
    }
    product_iter
}
error[E0308]: mismatched types
  --> src/testcode.rs:44:28
   |
10 |             product_iter = iproduct!(product_iter, list.iter());
   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::slice::Iter`, found struct `itertools::adaptors::Product`
   |
   = note: expected type `std::slice::Iter<'_, _>`
              found type `itertools::adaptors::Product<std::slice::Iter<'_, _>, std::slice::Iter<'_, u16>>`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

1 个答案:

答案 0 :(得分:4)

doc已经回答了您:

use itertools::Itertools; // 0.8.0

pub fn product_of_lists(lists: &[Vec<u16>]) -> impl Iterator<Item = Vec<&u16>> {
    // generate cross products between lists
    assert!(lists.len() > 2);
    lists.iter().map(|x| x.iter()).multi_cartesian_product()
}

use itertools::Itertools; // 0.8.0

pub fn product_of_lists<'a, L, I>(lists: L) -> impl Iterator<Item = Vec<&'a u16>>
where
    L: IntoIterator<Item = I>,
    I: IntoIterator<Item = &'a u16>,
    <I as IntoIterator>::IntoIter: Clone,
{
    lists
        .into_iter()
        .map(IntoIterator::into_iter)
        .multi_cartesian_product()
}