What is the best way to collect a tuple into a tuple of vectors?

I have code that returns an iterator of (u32, u32, u32) and I would like to collect that into a (Vec<u32>, Vec<u32>, Vec<u32>). What would be the best way to get that?

My current code is the following:

let (reds, greens, blues) = self
            .sub_games
            .iter()
            .map(|sub_game| {
                (
                    vec![sub_game.reds],
                    vec![sub_game.greens],
                    vec![sub_game.blues],
                )
            })
            .collect::<(Vec<u32>, Vec<u32>, Vec<u32>)>();

But this doesn't work, since that conversion seems to be unimplemeneted: "a value of type (Vec<u32>, Vec<u32>, Vec<u32>) cannot be built from an iterator over elements of type (u32, u32, u32)"

Does anyone have any suggestions? I know there are better ways to solve this, I'm mostly soving it this way to learn to use iterators better.

From Iterator::unzip docs:

// you can also unzip multiple nested tuples at once
let a = [(1, (2, 3)), (4, (5, 6))];

let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.iter().cloned().unzip();
assert_eq!(x, [1, 4]);
assert_eq!(y, [2, 5]);
assert_eq!(z, [3, 6]);

So that’s

    let (reds, (greens, blues)): (Vec<_>, (Vec<_>, Vec<_>)) = self
            .sub_games
            .iter()
            .map(|sub_game| {
                (
                    sub_game.reds,
                    (sub_game.greens, sub_game.blues),
                )
            })
            .unzip();

Alternatively, itertools has a variant of unzip that doesn’t require any extra steps of nesting tuples. Probably not worth pulling in itertools just for this, but if you’re having it anyways…

use itertools::Itertools;

    let (reds, greens, blues): (Vec<_>, Vec<_>, Vec<_>) = self
            .sub_games
            .iter()
            .map(|sub_game| {
                (
                    sub_game.reds,
                    sub_game.greens,
                    sub_game.blues,
                )
            })
            .multiunzip();
2 Likes

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.