How to combine 2 Vec into 1 tuple Vec?

I’m new to Rust. Could somebody help me on this? I want to combine Vec<u64> and Vec<Hash> into Vec<(u64, Hash)>.

Here is my draft code but can’t work: Rust Playground

#[derive(Copy, Clone)]
pub struct Hash(pub [u8; 32]);

impl Hash {
	pub fn from_vec(v: &[u8]) -> Hash {
		let mut h = [0; 32];
		let mut copy_size = v.len();
		if copy_size > 32 {
		    copy_size = 32;
		}
		h[..copy_size].copy_from_slice(&v[..copy_size]);
		Hash(h)
	}
}

fn main() {
    
    let mut comb: Vec<(u64, Hash)> = vec![];
    
    let hash1 = Hash::from_vec(&vec![8,8,8]);
    let hash2 = Hash::from_vec(&vec![9,9,9]);
    
    let mut heights: Vec<u64> = vec![1,2];
    let mut loc: Vec<Hash> = vec![hash1, hash2];

	comb = heights.iter()
		.flat_map(|&k| loc.iter().map(|v| (k,v)).into_iter() )
		.collect();
		
}

Only two tweaks needed:

	comb = heights.iter()
		.flat_map(|&k| loc.iter().map(move |&v| (k,v)))
		.collect();

The move makes sure that the inner closure takes ownership of k, and doesn’t only borrow it.

Thanks @birkenfeld, please check the modified code in Rust Playground , I print the result and it seems not correct. Could you take a look again?

It sounds like you’re looking for the Iterator::zip() function. This takes two iterators and turns them into a single iterator yielding pairs. A Vec<T> can be turned into an iterator, so your solution would be something like this:

comb = heights.into_iter()
  .zip(loc.into_iter())
  .collect();
4 Likes

Thanks @Michael-F-Bryan it works! :bouquet:

The final working code: https://play.rust-lang.org/?gist=befb52bfa1d2f369b6ed49fe83a77326&version=stable&mode=debug&edition=2015

2 Likes

Well, you didn’t describe how you wanted to combine the elements from the two vectors. Since your original code was closest to the cartesian product, I assumed that was the goal.

1 Like