6

Swift コードに次のループがあります。

for var i:Int = 0, j:Int = 0; i < rawDataOut.count; i += 4, ++j {
    maskPixels[j] = rawDataOut[i + 3]
}

Xcode で 2 つの警告が表示されます。

  1. C スタイルの for ステートメントは非推奨であり、Swift の将来のバージョンでは削除される予定です
  2. 「++」は非推奨です: Swift 3 で削除されます

Swift のFor In ループでこれを書き直して、2 つの変数と 4 ストライドを考慮に入れる方法がわかりません。シンプルでエレガントな翻訳はありますか?

4

2 に答える 2

17

これに答える前提条件: あなたの例を見て

ではなくibyで制限するつもりだったと思います。そうしないと、インデックスによる要素へのアクセスは、ランタイムの安全性に関してあまり意味がありません。とにかく、あなたが私たちを見せなくても、これは私たちがしなければならない仮定です.i < rawDataOut.count-3i < rawDataOut.countrawDataOut[i + 3]rawDataOut

したがって、元のループ (検証可能な例を含む) は次のようになります。

/* example data */
var rawDataOut = Array(1...40)
var maskPixels = [Int](count: 10, repeatedValue: 0)

/* your pre-Swift 2.2/3.0 loop */
for var i: Int = 0, j: Int = 0; i < rawDataOut.count-3; i += 4, ++j {
    maskPixels[j] = rawDataOut[i + 3]
}

print(maskPixels) //[4, 8, 12, 16, 20, 24, 28, 32, 36, 40]

使用するfor in ... where

あなたの特定の例では、複数のインクリメントには単純な関係 ( ) があるため、明示的な反復j=4*iを使用しなくてもこれを解決できます。j

/* example data */
var rawDataOut = Array(1...40)
var maskPixels = [Int](count: 10, repeatedValue: 0)

/* your pre-Swift 2.2/3.0 loop */
for i in 0..<(rawDataOut.count-3) where i%4 == 0 {
    maskPixels[i/4] = rawDataOut[i + 3]
}

print(maskPixels) // [4, 8, 12, 16, 20, 24, 28, 32, 36, 40]

しかし、これはおそらく、2 つの反復の一般的な議論にとってはあまり重要ではありません。と を組み合わせた 2 回反復法strideに進みenumerateます。


組み合わせstrideenumerate

1 つの解決策は、上記のループでstride反復によって記述されたものを列挙し、列挙インデックスを使用して 2 番目の反復 (上記) を構築することです。あなたの例では、インデックスは正確に対応しています。ijenumeratej

/* example data */
var rawDataOut = Array(1...40)
var maskPixels = [Int](count: 10, repeatedValue: 0)

/* Swift >= 2.2 loop */
for (j, i) in 0.stride(to: rawDataOut.count-3, by: 4).enumerate() {
    maskPixels[j] = rawDataOut[i + 3]
}

print(maskPixels) // [4, 8, 12, 16, 20, 24, 28, 32, 36, 40]

Swift 3 では (2.2 と比較して)、 (ブループリントされていない拡張メソッドとして)プロトコルのデフォルトの実装が廃止stride(to:by:)され、(Swift 1.2 のように) に戻っていることに注意してください。グローバル関数と、たとえば、 swift/stdlib/public/core/Stride.swiftの現在のマスター ブランチを参照してください。stride(through:by:)Strideablestride(from:to:by:)stride(from:through:by:)


トリッキーなケース: に頼るwhile

よりトリッキーなケースでは、Swift 2.2 より前のループで署名を次のように言います。

for var i: Int = 0, j: Int = 0; i < rawDataOut.count-3; i += 4, j += i { ... }

whileおそらく、ループ不変条件に関連付けられた 1 つの反復と、自由変数としての末尾の反復を含むループを使用するのが最善です。これが面倒だと思うかどうかは好みの問題だと思います。

var i = 0, j = 0
while i < rawDataOut.count-3 {

    // ...

    // increase iterates
    i += 4
    j += i
}

C スタイルのループを削除する理由は、ほとんどの場合、 などで直接カバーされているfor inためstrideだと思いwhileます。

于 2016-03-29T21:59:51.470 に答える
7

スウィフト4では

for index in stride(from: 0, to: 10, by: 2){
    print(index)
}
于 2017-10-27T05:44:34.793 に答える