Swiftの配列内を操作する方法

投稿者: Anonymous

現在、coreMLとVisionを使って画像の物体認識を行うアプリを作成中です。

以下のようなコーディングを行い、画像の物体認識した結果をデバッグエリアに出力しています。
その後、配列の0番目をbestに代入します。

func handleClassification(request: VNRequest, error: Error?) {
    guard let observations = request.results as? [VNClassificationObservation] else { fatalError() }
    //print("observations = ", observations)
    guard let best = observations.first else { fatalError() }

以下は出力結果です。

画像の説明をここに入力

配列の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 {
    //配列の順番は変更しない。
}
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *