How to search for an enum by values and why enum items aren't unique

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jul 19 22:45:21 PDT 2016


On Wednesday, July 20, 2016 04:03:23 stunaep via Digitalmars-d-learn wrote:
> How can I search for an enum by its values? For example I have
>
> >struct TestTraits {
> >
> > int value1;
> > string value2;
> >
> >}
> >
> >enum Test : TestTraits {
> >
> > TEST = TestTraits(1, "test1"),
> > TESTING = TestTraits(5, "test5")
> >
> >}
>
> and I have the int 5 and need to find TESTING with it.
>
> In java I would create a SearchableEnum interface, make all
> searchable enums implement it and use this method to find them.
>
> >public static <T extends SearchableEnum> T find(T[] vals, int
> >id) {
> >
> > for (T val : vals) {
> >
> >     if (id == val.getId()) {
> >
> >         return val;
> >
> >     }
> >
> > }
> > return null;
> >
> >}
>
> But the way enums work in D doesn't seem to permit this.

If you want the list of members in an enum, then use std.traits.EnumMembers
and you'll get a compile-time list of them. It can be made into a runtime
list by being put into an array literal.

For instance, if we take std.datetime.Month, we can look for the enum
with the value 10 in it like so.

auto found = [EnumMembers!Month].find(10);
assert(found = [Month.oct, Month.nov, Month.dec]);

So, if you had your TestTraits struct as the type for an enum, you could do
something like

auto found = [EnumMembers!TestTraits].find!(a => a.value1 == 5)();
if(found.empty)
{
    // there is no TestTraits which matches
}
else
{
    // found.front is the match
}

> And why on earth are different enum items with the same values
> equal to each other? Say I have an enum called DrawableShape

Because they have the same value. The fact that they're enums doesn't change
how they're compared. That's determined by what type they are. All you're
really getting with an enum is a list of named constants that are grouped
together which implicitly convert to their base type but which are not
converted to implicitly from their base type. The only stuff that's going to
treat an enum member differently from any other value of that type is
something that specifically operates on enums - e.g. by taking the enum type
explicitly, or because it has is(T == enum) and does something different for
enums (quite a few traits do that in std.traits), or because it uses a final
switch. Most code is just going to treat them like any other value of the
enum's base type. They aren't magically treated as unique in some way just
because they're in an enum.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list