Enum from String

前端 未结 18 1971
温柔的废话
温柔的废话 2020-12-15 14:54

I have an Enum and a function to create it from a String because i couldn\'t find a built in way to do it



        
相关标签:
18条回答
  • 2020-12-15 15:22

    Collin Jackson's solution didn't work for me because Dart stringifies enums into EnumName.value rather than just value (for instance, Fruit.apple), and I was trying to convert the string value like apple rather than converting Fruit.apple from the get-go.

    With that in mind, this is my solution for the enum from string problem

    enum Fruit {apple, banana}
    
    Fruit getFruitFromString(String fruit) {
      fruit = 'Fruit.$fruit';
      return Fruit.values.firstWhere((f)=> f.toString() == fruit, orElse: () => null);
    }
    
    0 讨论(0)
  • 2020-12-15 15:23

    There are a couple of enums packages which allowed me to get just the enum string rather than the type.value string (Apple, not Fruit.Apple).

    https://pub.dartlang.org/packages/built_value (this is more up to date)

    https://pub.dartlang.org/packages/enums

    void main() {
      print(MyEnum.nr1.index);            // prints 0
      print(MyEnum.nr1.toString());       // prints nr1
      print(MyEnum.valueOf("nr1").index); // prints 0
      print(MyEnum.values[1].toString())  // prints nr2
      print(MyEnum.values.last.index)     // prints 2
      print(MyEnum.values.last.myValue);  // prints 15
    }  
    
    0 讨论(0)
  • 2020-12-15 15:23

    another variant, how it might be solved:

    enum MyEnum {
      value1,
      value2,
    }
    
    extension MyEnumX on MyEnum {
      String get asString {
        switch (this) {
          case MyEnum.value1:
            return _keyValue1;
          case MyEnum.value2:
            return _keyValue2;
        }
        throw Exception("unsupported type");
      }
    
      MyEnum fromString(String string) {
        switch (string) {
          case _keyValue1:
            return MyEnum.value1;
          case _keyValue2:
            return MyEnum.value2;
        }
        throw Exception("unsupported type");
      }
    }
    
    const String _keyValue1 = "value1";
    const String _keyValue2 = "value2";
    
    void main() {
        String string = MyEnum.value1.asString;
        MyEnum myEnum = MyEnum.value1.fromString(string);
    }
    
    0 讨论(0)
  • 2020-12-15 15:31

    I had the same problem with building objects from JSON. In JSON values are strings, but I wanted enum to validate if the value is correct. I wrote this helper which works with any enum, not a specified one:

    class _EnumHelper {
    
    
     var cache = {};
    
      dynamic str2enum(e, s) {
        var o = {};
        if (!cache.containsKey(e)){
          for (dynamic i in e) {
            o[i.toString().split(".").last] = i;
          }
          cache[e] = o;
        } else {
          o = cache[e];
        }
        return o[s];
      }
    }
    
    _EnumHelper enumHelper = _EnumHelper();
    

    Usage:

    enumHelper.str2enum(Category.values, json['category']);
    

    PS. I did not use types on purpose here. enum is not type in Dart and treating it as one makes things complicated. Class is used solely for caching purposes.

    0 讨论(0)
  • 2020-12-15 15:31

    I use this function, I think it's simple and doesn't need any kind of 'hack':

    T enumFromString<T>(List<T> values, String value) {
        return values.firstWhere((v) => v.toString().split('.')[1] == value,
                                 orElse: () => null);
    }
    

    You can use it like this:

    enum Test {
        value1,
        value2,
    }
    
    var test = enumFromString(Test.value, 'value2') // Test.value2
    
    0 讨论(0)
  • 2020-12-15 15:32

    Mirrors aren't always available, but fortunately you don't need them. This is reasonably compact and should do what you want.

    enum Fruit { apple, banana }
    
    // Convert to string
    String str = Fruit.banana.toString();
    
    // Convert to enum
    Fruit f = Fruit.values.firstWhere((e) => e.toString() == str);
    
    assert(f == Fruit.banana);  // it worked
    

    Fix: As mentioned by @frostymarvelous in the comments section, this is correct implementation:

    Fruit f = Fruit.values.firstWhere((e) => e.toString() == 'Fruit.' + str);
    
    0 讨论(0)
提交回复
热议问题