質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

3回答

4658閲覧

Swift Objectからプロパティ名を動的に取得することは可能でしょうか?

yoppy0066

総合スコア293

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/10/31 05:43

編集2018/10/31 05:53

やりたいことのイメージは以下のようなことなのですが可能になりますでしょうか?

class User { var id: Int var name: String } var user = new User(id: 1, name: "ユーザー") var key = "name" user[key] // できない エラー

以下、補足になります。

Userの各プロパティをUITableViewに表示したいと考えています。
keys = ["name", "id"] 等で表示順を定義して、0番目だったら name を表示する。ということを考えていたのですが、
この実装をする場合にはプロパティ名を動的に指定して取得できなければならないため今回質問させて頂いた経緯となります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2018/10/31 05:47

このコードだけだと user.name でダメな理由が分かりません。
yoppy0066

2018/10/31 05:53

補足を追加させていただきました
guest

回答3

0

ベストアンサー

subscriptとリフレクションを使えば出来ないこともないですが・・・

swift:

1class User { 2 var id: Int 3 var name: String 4 5 init(id: Int, name: String) { 6 self.id = id 7 self.name = name 8 } 9 10 subscript(propName: String) -> String { 11 if let prop = Mirror(reflecting: self).children.first(where: { $0.label == propName }) { 12 return "(prop.value)" 13 } 14 return "" 15 } 16} 17 18let user = User(id: 1, name: "ユーザー") 19 20print(user["id"]) // 1 21print(user["name"]) // ユーザー

実際にこのようなコードで開発を行うことは、まず無いと思います。

本当に表示だけならいいかもしれませんが、表示を加工したり、編集機能を持たせようとしたりなどと、ちょっとでも他の事を実現しようと思ったら破綻すると思います。

投稿2018/10/31 06:31

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

keys = ["name", "id"]こういうのを生成する方法を考えると、その段階で危ういので、深く考えずに、

swift

1 2enum SortKey: String { 3 case id 4 case name 5} 6 7func label(_ user: User, _ sortKey: SortKey) -> String { 8 switch sortKey { 9 case .id: return String(user.id) 10 case .name: return user.name 11 } 12}

とかでいいのでは?

swift

1 2let u = // イニシャライザがないのでよくわからない 3 4let keys = ["id", "name", "実装忘れのキー"] 5 6let label0 = label(u, SortKey(rawValue: keys[0])!) 7 8let label1 = label(u, SortKey(rawValue: keys[1])!) 9 10let label2 = label(u, SortKey(rawValue: keys[2])!) // SortKeyが生成できないのでクラッシュ 11

実装忘れがあるとクラッシュする「安全」設計

投稿2018/10/31 08:50

編集2018/10/31 08:53
MasakiHori

総合スコア3384

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Mirror

調べながら書いたので変なところがあるかも知れませんが。

swift

1class User { 2 var id: Int = 123 3 var name: String = "hogehoge" 4} 5 6let user = User() 7let keys = ["name", "id"] 8let mirror = Mirror(reflecting: user) 9keys.forEach { key in 10 if let child = mirror.children.first(where: {$0.label == key}) { 11 print("(key) = (child.value)") 12 } 13}

text

1name = hogehoge 2id = 123

Dictionary

Dictionaryでいいんじゃないですかね。

swift

1let user: [String:Any] = ["id": 1, "name": "ユーザー"] 2let keys = ["name", "id"] 3keys.forEach { 4 if let value = user[$0] { 5 print("($0) = (value)") 6 } 7}

text

1name = ユーザー 2id = 1

投稿2018/10/31 05:58

編集2018/10/31 06:37
fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoppy0066

2018/10/31 06:03

ありがとうございした。APIから取得した値がすでにObjectに格納されてるため、入れ直す手間があるのですがもう少し検討してみます。
fuzzball

2018/10/31 06:13 編集

あなたの言っているObjectというのはクラスのことですかね?(Dictionaryもオブジェクトですが)
fuzzball

2018/10/31 06:35

追記しました。 正直、こんな訳の分からないコード書くくらいだったら、ifやswitchなどの条件分岐を使ってベタ書きする方がいいと思いますよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問