Enum collections

What's a good way to sort enum values by variant?

In some cases, it's possible to know and sort the enum variants as they're generated. In others, the collection gets deserialized from saved data whose ordering or contents can't be known in advance.

Right now, something similar to the following is used. Does anyone know if there are more idiomatic ways to express this?

enum X {
    B{b: usize},
    D{d: f32}

fn sort_by_variant(
    v: &[X]
) -> Vec<Vec<X>> {
        vec![vec![]; 4],
        |mut vv, x| {
            match x {
                X::A => { vv[0].push(*x); },
                X::B{..} => { vv[1].push(*x); },
                X::C => { vv[2].push(*x); },
                X::D{..} => { vv[3].push(*x); }   

Side note on terminology: This looks more like something I would express as "grouping" the enums by variant, rather than "sorting" them by variant.

I think the return type could be better. Since it's always 4 groups, -> [Vec<X>; 4] would already be better than -> Vec<Vec<X>>. Perhaps even nicer could be a struct

pub struct XsByVariant {
    pub a: Vec<X>,
    pub b: Vec<X>,
    pub c: Vec<X>,
    pub d: Vec<X>,

where Xs is the plural of X, and the fields are named after the variants. Then sort_by_variant (or maybe call it group_by_variant) would return -> XsByVariant.

Or, depending on how you plan to use this and which kind of API is easier to work with, it might even make sense to re-structure the enum so that each variant has its own dedicated type

enum X {
struct A;
struct B { b: usize }
struct C;
struct D { d: f32 }

then you could make sort_by_variant just return a quadruple -> (Vec<A>, Vec<B>, Vec<C>, Vec<D>), or perhaps even a custom struct like XsByVariant, but with fields of type Vec<A>, Vec<B>, etc.

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.