17

Is there a way to convert a string to an enum?

enum eCommand{fred, joe, harry}

eCommand theCommand= cast(eCommand, 'joe');??

I think I just have to search for the enum (eg loop).

cheers

Steve

Lymp
  • 933
  • 1
  • 7
  • 20

10 Answers10

13

I got annoyed with the state of enums and built a library to handle this:

https://pub.dev/packages/enum_to_string

Basic usage:

import 'package:enum_to_string:enum_to_string.dart';

enum TestEnum { testValue1 };

main(){
    final result = EnumToString.fromString(TestEnum.values, "testValue1");
    // TestEnum.testValue1
}

Still more verbose than I would like, but gets the job done.

Ryan Knell
  • 6,204
  • 2
  • 40
  • 32
12

Dart 2.6 introduces methods on enum types. It's much better to call a getter on the Topic or String itself to get the corresponding conversion via a named extension. I prefer this technique because I don't need to import a new package, saving memory and solving the problem with OOP.

I also get a compiler warning when I update the enum with more cases when I don't use default, since I am not handling the switch exhaustively.

Here's an example of that:

enum Topic { none, computing, general }

extension TopicString on String {
  Topic get topic {
    switch (this) {
      case 'computing':
        return Topic.computing;
      case 'general':
        return Topic.general;
      case 'none':
        return Topic.none;
    }
  }
}

extension TopicExtension on Topic {
  String get string {
    switch (this) {
      case Topic.computing:
        return 'computing';
      case Topic.general:
        return 'general';
      case Topic.none:
        return 'none';
    }
  }
}

This is really easy to use and understand, since I don't create any extra classes for conversion:

var topic = Topic.none;
final string = topic.string;
topic = string.topic;

(-:

Pranav Kasetti
  • 8,770
  • 2
  • 50
  • 71
9

I have came up with a solution inspired from https://pub.dev/packages/enum_to_string that can be used as a simple extension on List

extension EnumTransform on List {
  String string<T>(T value) {
    if (value == null || (isEmpty)) return null;
    var occurence = singleWhere(
        (enumItem) => enumItem.toString() == value.toString(),
        orElse: () => null);
    if (occurence == null) return null;
    return occurence.toString().split('.').last;
  }

  T enumFromString<T>(String value) {
    return firstWhere((type) => type.toString().split('.').last == value,
        orElse: () => null);
  }
}

Usage

enum enum Color {
  red,
  green,
  blue,
}

var colorEnum = Color.values.enumFromString('red');
var colorString: Color.values.string(Color.red)
Alpexs
  • 91
  • 2
  • 2
6

As of Dart 2.15, you can use the name property and the byName() method:

enum eCommand { fred, joe, harry }
eCommand comm = eCommand.fred;

assert(comm.name == "fred");
assert(eCommand.values.byName("fred") == comm);

Just be aware that the byName method throws an ArgumentError if the string is not recognized as a valid member in the enumeration.

Nathan Dudley
  • 510
  • 7
  • 17
3

For the Dart enum this is a bit cumbersome.

See Enum from String for a solution.

If you need more than the most basic features of an enum it's usually better to use old-style enums - a class with const members.

See How can I build an enum with Dart? for old-style enums

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
3

This is the fastest way I found to do this :

enum Vegetable { EGGPLANT, CARROT, TOMATO }
Vegetable _getVegetableEnum(dynamic myVegetableObject) {
  return Vegetable.values.firstWhere((e) => describeEnum(e) == myVegetableObject);
}
Jack'
  • 1,722
  • 1
  • 19
  • 27
2

i had the same problem, a small enum and a string, so i did this

dynamic _enum_value = EnumFromString(MyEnum.values, string_to_enum);

dynamic EnumFromString(List values, String comp){
  dynamic enumValue = null;
  values.forEach((item) {
    if(item.toString() == comp){
      enumValue =  item;
    }
  });
  return enumValue;
}

i know this is not the best solution, but it works.

wblaschko
  • 3,252
  • 1
  • 18
  • 24
0

Static extension methods would make this nice (currently unimplemented).

Then you could have something like this:

extension Value on Keyword {
  /// Returns the valid string representation of a [Keyword].
  String value() => toString().replaceFirst(r'Keyword.$', '');

  /// Returns a [Keyword] for a valid string representation, such as "if" or "class".
  static Keyword toEnum(String asString) =>
      Keyword.values.firstWhere((kw) => kw.value() == asString);
}
0

FOUND ANS

  • Check this article. Very well explained: Link

    extension EnumParser on String {
       T toEnum<T>(List<T> values) {
          return values.firstWhere(
               (e) => e.toString().toLowerCase().split(".").last == 
               '$this'.toLowerCase(),
               orElse: () => null,
          ),
       }
    }
    
kunj kanani
  • 324
  • 4
  • 5
0

The cleanest way is to use built-in functionality:

enum EmailStatus {
  accepted,
  rejected,
  delivered,
  failed,
}

EmailStatus.values.byName('failed') == EmailStatus.failed; => true

Arne Wolframm
  • 367
  • 4
  • 16