質問: observations.first else { fatalError() } ``` 以下は出力結果です。 ![画像の説明をここに入力](https://i.stack.imgur.com/soata.png) 配列の0番目の要素はsoccerで推測値が0.909137 配列の1番目の要素はbaseballで推測値が0.087247 といった感じで並んでいます。 画像の物体認識した結果後、配列内の要素の順番を変更したいのですが、やり方がわかりません。 (やってみたいことははっきりとしているのですが、解決方法がわかりません) ■やってみたいこと 画像の物体認識した結果後、 もしbaseballの推測値が0.080000以上のときは、baseballを配列の0番目に変更したいです。 baseballの推測値が0.080000より小さいときは、配列の順番を変更しない。 if文で記述すると以下のような感じになると思います。 ``` if baseballの推測値が0.080000以上だったら { baseballを配列の0番目に置く。 } baseballの推測値が0.080000より小さかったら { 配列の順番は変更しない。 } ``` 独学でSwiftを学んでいるため分からないことが多いのですが、 そもそも上記のような配列内の操作は可能なのでしょうか。 ご教示いただけますでしょうか、宜しくお願いします。 --- --- ■追記 配列の要素を入れ替える方法は、こちらの記事を参考に実装したいと思います。 そのため、以下のようなコーディングを目指しています。 ``` if baseballの推測値が0.080000以上だったら { 配列内のbaseballのindex番号を調べる。 例えば、画像認識の結果、baseballのindex番号が配列の4番目の場合は、 配列の0番目と4番目を入れ替える。 } baseballの推測値が0.080000より小さかったら { 配列の順番を変更しない。 } ``` 現在は、配列内でbaseballの推測値が0.080000以上であるのか baseballの推測値が0.080000より小さいのかを察知する方法が 分かりません。 お手数をおかけ致しますがご教示頂けますでしょうか。 宜しくお願い致します。
回答: 何点かポイントを。 * 配列(あなたの`observations`)を`let`で宣言すると、その中身を後から変更することはできません。`guard let`ほどポピュラーなイディオムではありませんが、Swiftでは`guard var`なんて宣言もできます。 * `baseballの推測値が0.080000以上だったら`なんて条件を少し書き換えて、「信頼度が0.080000以上で識別子が`"baseball"`の要素があれば」と読み替えてみます。Swiftの`Array`には大変汎用性の高い`index(where:)`と言うメソッドがあるので、それを使えば判定と同時にそのindex番号を得ることができます。 * (現在の)Swiftの`Array`には、`swapAt(_:_:)`というメソッドがあるので、特別に要素入れ替え用の`extension`を定義する必要はありません。 以上をコードの形にまとめると、こんな感じになります。 ``` guard var observations = request.results as? [VNClassificationObservation] else { fatalError() } //print("observations = ", observations) //`identifier`が"baseball"で、`confidence`が0.080000以上の要素のindexを取得する if let baseballIndex = observations.index(where: {$0.identifier == "baseball" && $0.confidence >= 0.080000}) { //取得できたならそのindexと0番目を入れ替え observations.swapAt(0, baseballIndex) } else { //配列の順番は変更しない。 } ```