Swift:列挙値を文字列に変換しますか?


141

次の列挙型があるとします。

enum Audience {
    case Public
    case Friends
    case Private
}

以下"Public"audience定数から文字列を取得するにはどうすればよいですか?

let audience = Audience.Public

2
それはあなたがそのようなことを達成する方法についていくつかのアイデアを与える可能性があり、この答えをチェックしてください:stackoverflow.com/questions/24648726/enums-with-data-in-swift/...
holex

Swift 2とxcode7では、コードを変更する必要はありません。使用するだけですprint("\(audience)")
gbdavid

7
Swiftエコスケープがこのような非常に日付の古い回答で満たされているのは嫌です。XCode8.2 / Swift3と同じくらい簡単ですString(describing: yourEnumValue)
Travis Griggs

@TravisGriggs Xcode 11.4では動作しません
DawnSong

回答:


156

この機能が追加されたSwiftのバージョンはわかりませんが、現在(Swift 2.1)に必要なコードは次のとおりです。

enum Audience : String {
    case public
    case friends
    case private
}

let audience = Audience.public.rawValue // "public"

文字列が未加工の値に使用される場合、各ケースの暗黙的な値は、そのケースの名前のテキストです

[...]

enum CompassPoint : String {
    case north, south, east, west
}

上記の例では、CompassPoint.southの暗黙的な生の値は「south」などです。

rawValueプロパティを使用して、列挙型ケースの生の値にアクセスします。

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

ソース。


8
xcode7.3のswift2.2では、次のような print("appState: \(application.applicationState)") こと appState: UIApplicationState をすると、これはタイプであり、列挙値の実際の文字列表現ではありません。ここで何か不足していますか?(PS:rawValueの場合、Int値を取得します...)
Martin

@Cyrusのシナリオは、このスレッドで尋ねられたものとは異なります。.rawValue列挙型の生の値を返します。あなたのpublic enum UIApplicationState : Intものは確かにタイプIntです。また、Appleのドキュメントからの引用がある私の回答を読んだこともありません。...それでもUIApplicationState文字列に変換したい場合UIApplicationStateは、カスタムの計算プロパティで拡張することをお勧めしますextension UIApplicationState { var toString() -> String { /* check self for all diff. cases and return something like "Active" */ }
DevAndArtist

String型ではない列挙型の問題を解決しない
denis631

1
@ denis631どういう意味ですか?enumのrawタイプは何でもかまいません。enumは、OptionSet本当に必要な場合にも準拠できます。元の質問はとにかく文字列についてです。
DevAndArtist 2018年

1
enumが次のように記述されている場合、enum Test:Int {case A、B}、rawValueはもちろんintを返します。探しているのは、ケースの名前を文字列として取得する方法です。これはまさに@DanilShaykhutdinovがやったことです。彼の答えを見てください。元の質問では、列挙型には型がなく、文字列や整数もありません。
denis631 2018年

209

「文字列を取得する」ための慣用的なインターフェースは、CustomStringConvertible インターフェースを使用してdescriptionゲッターにアクセスすることです。enumとして定義:

enum Foo : CustomStringConvertible {
  case Bing
  case Bang
  case Boom
  
  var description : String { 
    switch self {
    // Use Internationalization, as appropriate.
    case .Bing: return "Bing"
    case .Bang: return "Bang"
    case .Boom: return "Boom"
    }
  }
}

実行中:

 > let foo = Foo.Bing
foo: Foo = Bing
 > println ("String for 'foo' is \(foo)"
String for 'foo' is Bing

更新:Swift> = 2.0の場合PrintableCustomStringConvertible

:を使用CustomStringConvertibleするFooと、別のrawタイプを採用できます。たとえばenum Foo : Int, CustomStringConvertible { ... }可能です。この自由は役に立ちます。


2
println文字列を作成するもう1つの短い方法は、次のとおりです。「String for 'foo' is(foo)」
John MP Knox

3
@ JohnM.P.Knoxは、「String for 'foo' is \(foo)」のようにバックスラッシュを忘れないでください。編集 OKは、それは編集者がそれを退治だ、私はそれが現れるようにするためにそれらの2を入力する必要がありました
zmit

これがCustomStringConvertibleなくても同じように機能する場合、何が重要ですか?
Daniel van der Merwe 2016年

3
CustomStringConvertibledescriptionenumの各ケースにどの文字列を使用するかを決定できるように定義することを許可/要求します-これは国際化にとって、そしておそらくコードの可読性にとって重要です。それらを気にしない場合は、 'enum Foo:String {/ * ... * /} `を使用できます
GoZoner

2
enumが文字列でない場合、またはrawValueとは異なる文字列が必要な場合は、これが正しい答えです。@ denis631
Haagenti

32

ここでは、列挙型を次のように再定義します。

enum Audience: String {
    case Public = "Public"
    case Friends = "Friends"
    case Private = "Private"
}

私ができるように:

audience.toRaw() // "Public"

しかし、この新しい列挙型定義は冗長ではありませんか?最初の列挙型の定義を保持して、次のようなことはできますか?

audience.toString() // "Public"

3
Xcode 7 Beta 3 = String以降は、答えを書くことができますが、何も指定しないと生の値(ケースの名前)が自動的に取得されるため、答えを書く必要はありません。
Qbyte

3
.toString()の代わりに.rawValueを使用する
SoftDesigner 2015

Swift 1.2では、次を使用できます。println(Audience.Friends.rawValue)
Oleg Popov

32

Swift 3では、これを使用できます

var enumValue = Customer.Physics
var str = String(describing: enumValue)

Swiftから列挙型を使用して文字列値を取得する方法


2
これは、特に私enumStringsに基づいていない場合に非常に役立ちます
ダスピアニスト2017年

1
"\(enumValue)"同じことをします。^^
eonist

これはより良い答えです。列挙型のString型を作成する必要はありません。
19

24

で使用するのPrintableが好きRaw Valuesです。

enum Audience: String, Printable {
    case Public = "Public"
    case Friends = "Friends"
    case Private = "Private"

    var description: String {
        return self.rawValue
    }
}

その後、次のことができます。

let audience = Audience.Public.description // audience = "Public"

または

println("The value of Public is \(Audience.Public)") 
// Prints "The value of Public is Public"

1
私はできるので、選択した回答よりもこの方法が好きですAudience(rawValue: "Friends")
tidwall 2015年

12

Xcode 7 GMのリリース用に更新されました。それは今望んでいるように機能します-アップルに感謝します!

enum Rank:Int {
    case Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
}

let r = Rank.Ace

print(r)               // prints "Ace"
print("Rank: \(r)!")   // prints "Rank: Ace!"

2
Swift 2.0では、に準拠すれCustomStringConvertibleprint(r)、この場合でも実際に使用できます。
matm 2015

Xcode 7ベータ4では、Mirror(reflecting:x)のために、reflect()が無効になっているようです。ただし、返されるオブジェクトの構造は異なります。
GSnyder 2015

1
回答を更新してください
Ben Sinclair

10

Swift 2と最新のXcode 7では、これより簡単にすることはできません(列挙型、.rawValue、記述子などを指定する必要はありません)。

Swift 3およびXcode 8用に更新:

    enum Audience {
        case Public
        case Friends
        case Private
    }

    let audience: Audience = .Public  // or, let audience = Audience.Public
    print(audience) // "Public"

Intでサポートされている列挙型で完全に機能しました
chrislarson、

単なる観察:これは自己作成の列挙型では機能しますが、HKWorkoutActivityTypeなどの機能では機能しません
Ace Green

ローカライズされた文字列と同様に;)
Eugene Braginets

2
元の質問は、列挙値を独自の列挙型の文字列に変換することに関するものでした。そのため、私はそれに答えました... UIKit / AppKit Enumsを処理したい場合は、もちろん別の話です。
gbdavid 2016年

1
@gbdavid-UIKit / AppKit EnumsのQはありますか?私はグーグルでそれを見つけることができませんでした。必要な場合はQを送信できます。
18年

8

EnumでIntsを使用する場合の迅速な3以上の例

public enum ECategory : Int{
        case Attraction=0, FP, Food, Restroom, Popcorn, Shop, Service, None;
        var description: String {
            return String(describing: self)
        }
    }

let category = ECategory.Attraction
let categoryName = category.description //string Attraction

エレガントなソリューション。"\(category)"または直接String(describing:category)も機能します。Int列挙型についてもです。
t1ser

8

「The Swift Programming Language」の「A Swift Tour」の章の例を読んでいて、simpleDescription()メソッドを単純化する方法を探している人は、列挙型自体を文字列に変換するString(self)ことで実現できます。

enum Rank: Int
{
    case Ace = 1 //required otherwise Ace will be 0
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() -> String {
        switch self {
            case .Ace, .Jack, .Queen, .King:
                return String(self).lowercaseString
            default:
                return String(self.rawValue)
        }
     }
 }

2
「@objc」で列挙型を使用していないことを確認してください。そのため、このアプローチは失敗します。
Matt

5

いくつかの異なる方法を試した後、使用したくない場合は、次のことがわかりました。

let audience = Audience.Public.toRaw()

あなたはまだ構造体を使用してそれをアーカイブすることができます

struct Audience {
   static let Public  = "Public"
   static let Friends = "Friends"
   static let Private = "Private"
}

次にあなたのコード:

let audience = Audience.Public

期待どおりに動作します。それはきれいではなく、「列挙型」を使用しないため、いくつかの欠点があります。ショートカットを使用して.Privateを追加するだけでは、スイッチケースでは機能しません。


きちんと見えます。この特定のケースのベストプラクティスは何でしょうか。単純さのためにstruct構文を使用したいと思いますが、enumの代わりにstructを使用することは正しくないように思われますか、それとも私だけですか?さて、定数変数を他の場所で宣言することを妨げるものは何もありません。今回は、構造化されるように構造体の中に追加するだけです。考え?
schystz 2015年

正確には、定数変数として機能しますが、より整理されています。前に言ったように、唯一の問題は「スイッチケース」とショートカット「.Private」です。アプリをゼロから構築する場合は、「列挙型」を使用してみてください。何らかの理由で「列挙型」がコードを満たさない場合にのみ、構造体を使用してください。私は個人的に定数変数を避け、代わりに常に構造体を使用しています。
Adriano Spadoni

これをデフォルトのキーに使用します。アプリ内のデフォルトのキーを覚えるのではなく、キーを構造体にダンプしてそこからプルします。
エイドリアン

3

これには複数の方法があります。列挙型の値に基づいて文字列を返す関数を列挙型で定義することもできます。

enum Audience{
    ...
func toString()->String{
  var a:String

  switch self{
   case .Public:
    a="Public"
   case .Friends:
    a="Friends"
   ...
 }
 return a
}

または、これを試すことができます:

enum Audience:String{
   case Public="Public"
   case Friends="Friends"
   case Private="Private"
}

そしてそれを使うには:

var a:Audience=Audience.Public
println(a.toRaw())

1

Swift 3.0以降では、

var str = String(describing: Audience.friends)

1
信じられないが、それは完全に動作します。「慣用的」アプローチよりもはるかに短い。ありがとう!
ローマ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.