🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

810閲覧

associated valueを持つenumの配列から配列のindexを返す方法

hameji

総合スコア1380

Swift

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2019/12/07 16:20

編集2019/12/07 16:27

いつも勉強させてもらっています。

タイトルの通り、associated valueを持つenumを作成し、
それを配列にして利用しています。

配列の変更が起こり得るので、その時点でのenumの条件のindexを取得し、
それをもとにenumにわけ、処理をしたいのですが、
どのようにしたらうまくindexを取得できるでしょうか?

stackoverflowにぴったり一致するものがありましたので、
参考に適応してみましたが、変数にして行うと、型が一致しているのに、しませんってエラーが出て困っております。

皆様の智恵をいただければ幸いです。

簡略化したサンプルを載せてみます。

Swift

1// CDCellのEnum 2enum CDPresentCell { 3 case titleCell(String?) 4 case artistCell(String?) 5 case releaseCell(Date?) 6} 7 8// CollectionView 9import UIKit 10 11class CDViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { 12 @IBOutlet weak var collectionView: UICollectionView! 13 @IBOutlet weak var datePicker: UIDatePicker! 14 var cells:[CDPresentCell] 15 16 init() { 17 self.cells = [.titleCell(nil), 18 .artistCell(nil), 19 .releaseCell(nil) 20 ] 21 } 22 23 // 試した1個目 <- CDPresentCell と CDPresentCellが一致しないというエラーが出ました。 24 private fun returnRow1(cell: CDPresentCell) -> Int? { 25 var m: Int? = nil 26 for n in 0 ..< self.cells.count { 27 if cell == self.cells[n] { 28 m = n 29 } 30 } 31 return m 32 } 33 34 // コレ試した2個目 <- CDPresentCell と CDPresentCellが一致しないというエラーが出ました。 35 private func returnRow2(cell: CDPresentCell) -> Int? { 36 if let index = self.cells.firstIndex(where: { if case cell.self = $0 { return true }; return false }) { 37 return index 38 } 39 return nil 40 } 41 42 override func viewDidLoad() { 43 } 44 45 @IBAction func doneButtonPressed(_ sender: Any) { 46 if let row = self.collectionView.indexPathsForSelectedItems?.first?.row { 47 let cellType = self.cells[row] 48 switch cellType { 49 case .releaseCell(let data): 50 self.datePicker.alpha = 1.0 51 default: break 52 } 53 } 54 } 55 56 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 57 return self.cells.count 58 } 59 60 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 61 let cellType = self.cells[indexPath.row] 62 switch cellType { 63 case .titleCell(let data): 64 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "title", for: indexPath) as! TitleCell 65 cell.bind(data: data) 66 return cell 67 case .artistCell(let data): 68 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "artist", for: indexPath) as! ArtistCell 69 cell.bind(data: data) 70 return cell 71 case .releaseCell(let data): 72 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "release", for: indexPath) as! ReleaseCell 73 cell.bind(data: data) 74 return cell 75 } 76 77 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 78 let cellType = self.cells[row] 79 switch cellType { 80 case .releaseCell(let data): 81 self.datePicker.alpha = 1.0 82 default: break 83 } 84 } 85 86 // collectionCellのtextFieldなどにdelegateを設定し、 87 // returnする場合にrowを数値で指定せずに、cellPresenterのself.cellsの 88 // enumからindexを取得し、更新に利用したいです。 89 func artistTextFieldDidReturn(text: String) { 90 let row = returnRow2(cell: .artist) // コレが働くようにしたい 91 let cellType = self.cells[row] 92 switch cellType { 93 case .titleCell(let data): 94 self.cells[row] = .titleCell(text) 95 default: break 96 } 97 self.collectionView.reloadItems(at: [[0, row]]) 98 } 99} 100

イメージ説明

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

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

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

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

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

MasakiHori

2019/12/08 05:11

case が一致しているかどうかを調べる方法を質問していますか? それともassociated valueも一致しているかどうかを調べる方法を質問していますか?
hameji

2019/12/08 09:41

わかりずづらくてすみません。 case が一致するindexを返したいです。 associated valueの内容は判定しなくていいです。
guest

回答1

0

ベストアンサー

switch文を使うのが分かりやすいでしょう。

swift

1let a = CDPresentCell.titleCell(nil) 2let b = CDPresentCell.titleCell("b") 3 4switch (a, b) { 5case (.titleCell, .titleCell): print("same") 6case (.artistCell, .artistCell): print("same") 7case (.releaseCell, .releaseCell): print("same") 8default: print("not same") 9}

これをenum自身に判別させるのが楽でしょう

extension CDPresentCell { func isSameCase(other: CDPresentCell) -> Bool { switch (self, other) { case (.titleCell, .titleCell): return true case (.artistCell, .artistCell): return true case (.releaseCell, .releaseCell): return true default: return false } } }

こうしておけば

swift

1private func returnRow2(cell: CDPresentCell) -> Int? { 2 return cells.firstIndex { $0.isSameCase(other: cell) } 3}

となります。

投稿2019/12/08 12:50

MasakiHori

総合スコア3391

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

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

hameji

2019/12/08 13:48

ありがとうございます。 そんなふうに、2つの要素を用いて、switchで比較できるんですね。 勉強になりました。スッキリです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問