web-dev-qa-db-ja.com

Swiftでは、文字列を列挙型に変換することは可能ですか?

ケースa、b、c、dの列挙型がある場合、文字列 "a"を列挙型としてキャストできますか?

77
user2763173

承知しました。列挙型は生の値を持つことができます。ドキュメントを引用するには:

生の値は、文字列、文字、または整数型または浮動小数点型のいずれかです

—抜粋:Apple Inc.「Swiftプログラミング言語。」iBooks。 https://itun.es/us/jEUH0.l

したがって、次のようなコードを使用できます。

enum StringEnum: String 
{
  case one = "one"
  case two = "two"
  case three = "three"
}

let anEnum = StringEnum(rawValue: "one")!

print("anEnum = \"\(anEnum.rawValue)\"")

注:各ケースの後に= "one"などを記述する必要はありません。デフォルトの文字列値はケース名と同じなので、.rawValueを呼び出すと文字列が返されます

編集

文字列値にケース値の一部として無効なスペースなどを含める必要がある場合は、文字列を明示的に設定する必要があります。そう、

enum StringEnum: String 
{
  case one
  case two
  case three
}

let anEnum = StringEnum.one
print("anEnum = \"\(anEnum)\"")

与える

anEnum = "one"

ただし、caseoneに「値1」を表示するには、文字列値を指定する必要があります。

enum StringEnum: String 
{
  case one   = "value one"
  case two   = "value two"
  case three = "value three"
}
114
Duncan C

あなたが必要なのは:

enum Foo: String {
   case a, b, c, d
}

let a = Foo(rawValue: "a")
assert(a == Foo.a)

let ???? = Foo(rawValue: "????")
assert(???? == nil)
24
emlai

Swift 4.2では、rawValuesを持つ列挙に対してCaseIterableプロトコルを使用できますが、文字列は列挙のケースラベルと一致する必要があります。

enum MyCode : String, CaseIterable {

    case one   = "uno"
    case two   = "dos"
    case three = "tres"

    static func withLabel(_ label: String) -> MyCode? {
        return self.allCases.first{ "\($0)" == label }
    }
}

使用法:

print(MyCode.withLabel("one")) // Optional(MyCode.one)
print(MyCode(rawValue: "uno"))  // Optional(MyCode.one)
16
djruss70

Int型の列挙型の場合、次のようにできます。

enum MenuItem: Int {
    case One = 0, Two, Three, Four, Five //... as much as needs

    static func enumFromString(string:String) -> MenuItem? {
        var i = 0
        while let item = MenuItem(rawValue: i) {
            if String(item) == string { return item }
            i += 1
        }
        return nil
    }
}

そして使用:

let string = "Two"
if let item = MenuItem.enumFromString(string) {
    //in this case item = 1 
    //your code
} 
14
Igor

Swift 4.2:

public enum PaymentPlatform: String, CaseIterable {
    case visa = "Visa card"
    case masterCard = "Master card"
    case cod = "Cod"

    var nameEnum: String {
        return Mirror(reflecting: self).children.first?.label ?? String(describing: self)
    }

    func byName(name: String) -> PaymentPlatform {
        return PaymentPlatform.allCases.first(where: {$0.nameEnum.elementsEqual(name)}) ?? .cod
    }
}
2
mr.boyfox

Duncan Cの答えを拡張する

extension StringEnum: StringLiteralConvertible {

    init(stringLiteral value: String){
        self.init(rawValue: value)!
    }

    init(extendedGraphemeClusterLiteral value: String) {
        self.init(stringLiteral: value)
    }

    init(unicodeScalarLiteral value: String) {
        self.init(stringLiteral: value)
    }
}
1
gujci