2

I want to devise a function similar to the example here except in my case, the number of arguments to iproduct is unknown at compile time. This is easily done in python as explained here.

I have tried using the itertools crate, specifically iproduct!, multi_cartesian_product and cartesian_product but currently fighting with the type system, as well as unsure if it is the right path.

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)
Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305
precious
  • 21
  • 1

1 Answers1

4

The doc already answer you:

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

or

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()
}
Stargateur
  • 24,473
  • 8
  • 65
  • 91