Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get "expected u32, found &{integer}" when pushing into a vector using iterators from the permutator crate?

I wanted to create a function that returns a data structure with all possible combinations for a certain group of numbers: e.g.: for [1, 2, 3] return [[1], [2], [3], [1, 2], [2,1], ..., [1, 2, 3], [2, 1, 3], ...[3, 2, 1]].

I understand that c and p are some kind of vector of &integer, but I cannot find a way to save them into an array or vector. I was trying to save it as a vector of vectors since I do not think it is possible to save them as a vector of arrays, since the arrays have different sizes. It's also not possible as an array of vectors since I do not know the number of combinations at the start.

How can I store all c and p in a data structure so that it can be returned and used outside?

use permutator::{Combination, Permutation}; // 0.3.3

pub fn init() -> Vec<Vec<u32>> {
    let actions: Vec<Vec<u32>>;
    let mut data = &[1, 2, 3];
    let mut counter = 1;
    for i in 1..=data.len() {
        data.combination(i).for_each(|mut c| {
            println!("{:?}", c);
            actions.push(c);
            c.permutation().for_each(|p| {
                println!("k-perm@{} = {:?}", counter, p);
                counter += 1;
                actions.push(p);
            });
        });
    }
    actions
}

The error I'm getting is:

error[E0308]: mismatched types
  --> src/main.rs:10:26
   |
10 |             actions.push(c);
   |                          ^ expected u32, found &{integer}
   |
   = note: expected type `std::vec::Vec<u32>`
              found type `std::vec::Vec<&{integer}>`

error[E0308]: mismatched types
  --> src/main.rs:14:30
   |
14 |                 actions.push(p);
   |                              ^ expected u32, found &{integer}
   |
   = note: expected type `std::vec::Vec<u32>`
              found type `std::vec::Vec<&{integer}>`

edit: When trying actions.push(c.iter().cloned().collect()) it returns the following error:

error[E0277]: a collection of type `std::vec::Vec<u32>` cannot be built from an iterator over elements of type `&u32`
  --> src/rl.rs:59:44
   |
59 |             actions.push(c.iter().cloned().collect());
   |                                            ^^^^^^^ a collection of type `std::vec::Vec<u32>` cannot be built from `std::iter::Iterator<Item=&u32>`
   |
   = help: the trait `std::iter::FromIterator<&u32>` is not implemented for `std::vec::Vec<u32>`


like image 925
Miguel Avatar asked Oct 24 '25 08:10

Miguel


1 Answers

When trying actions.push(c.iter().cloned().collect()) it returns the following error...

This happens because c is a Vec<&u32>, and .iter() iterates over references to items, so c.iter() is an iterator over &&u32s. .cloned() removes one of the &s but not the second one. You could fix this by adding another .cloned() (or .copied()), but I prefer to use .map:

actions.push(c.iter().map(|c| **c).collect());

If you don't need to keep around the references, you can instead shadow c with a Vec<u32> to use inside the loop:

let c: Vec<u32> = c.into_iter().cloned().collect();

cloned works here because c.into_iter(), unlike c.iter(), consumes the Vec<u32> to return an iterator over u32s.

I also don't see a good reason to use for_each here in place of a regular for loop. Here's how I would suggest writing init:

pub fn init() -> Vec<Vec<u32>> {
    let actions: Vec<Vec<u32>>;
    let data = &[1, 2, 3];
    let mut counter = 1;
    for i in 1..=data.len() {
        for c in data.combination(i) {
            let mut c = c.into_iter().cloned().collect();
            println!("{:?}", c);
            actions.push(c.clone());
            for p in c.permutation() {
                println!("k-perm@{} = {:?}", counter, p);
                counter += 1;
                actions.push(p);
            }
        }
    }
    actions
}

actions.push(p) works here without .into_iter().cloned().collect() because permutator::HeapPermutationIterator does the cloning internally.

like image 77
trent Avatar answered Oct 27 '25 00:10

trent



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!