Unpack Vec of structs

Hi all,

Say I have:

struct KmerMap {
        len: usize,
        map: HashMap<Vec<u8>, i32>,
    }

And a Vec<KmerMap> with three different len values.

What (if any) is the best way to unpack the HashMap's into three variables? i.e.

let x = Vec::new();
x.push(KmerMap {
        len: 2,
        map: HashMap<K, V>,
    });

x.push(KmerMap {
        len: 3,
        map: HashMap<K, V>,
    });

x.push(KmerMap {
        len: 4,
        map: HashMap<K, V>,
    });

let (map_len_2, map_len_3, map_len_4) = match x {
    ..?
}

Thanks!
M

If you're okay with unpacking into three variables of type KmerMap instead of their internal HashMaps you could do:

match x.as_slice() {
    [two, three, four] => {
        // Do something with two, three, four
    }
    [..] => {} // Needed to make the patterns exhaustive 
}

If you really want the HashMaps themselves you could do something like:

let maps = x.iter().map(|kmer| &kmer.map).collect::<Box<[_]>>();
match maps.as_ref() {
    [map_two, map_three, map_four] => {
        // Do something with two, three, four
    }
    [..] => {} // Needed to make the patterns exhaustive 
}

Also note in the above that if you care exclusively about the case where x is of length 3, you could use if let instead of match.

1 Like

Thanks for this! This is great.

I presume here:

[map_two, map_three, map_four] => {
        // Do something with two, three, four
    }

I can only use two, three, four in the scope of those curly brackets. How do I assign them to those variables to use later? Is that possible?

Do you mean that your vec has only 3 KmerMaps or that it only contains lots of KmerMaps with 3 different len values ? For the first case you can into_iter and call next three times. For the second case, "just" reduce to a map of collections HashMap<usize, Vec<KmerMap>> if the len values are known, you can reduce to a custom struct.

1 Like

Without something quite clunky like pre-declaring three identifiers at the function-level scope, as far as I'm aware no. You can reduce the scope nesting with if let like so:

if let [map_two, map_three, map_four, ..] = maps.as_ref() {
    // Do something with these variables
}

Fundamentally this tension is a result of the pattern being refutable.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.