48

Swift3で次のように書くにはどうすればよいですか?

for (f = first; f <= last; f += interval)          
{
    n += 1
}

これは私自身の試みです

for _ in 0.stride(to: last, by: interval)
{
    n += 1
}
4

5 に答える 5

69

Swift 2.2 -> 3.0: Strideable:sはグローバル関数stride(...)に置き換えられましたstride(...)

Swift 2.2 では、(あなた自身の試みで試したように) 設計図の (そしてデフォルトで実装された) 関数stride(through:by:)stride(to:by:) プロトコルから利用することができます。Strideable

/* Swift 2.2: stride example usage */
let from = 0
let to = 10
let through = 10
let by = 1
for _ in from.stride(through, by: by) { } // from ... through (steps: 'by')
for _ in from.stride(to, by: by) { }      // from ..< to      (steps: 'by')

一方、Swift 3.0 では、これら 2 つの関数は削除され、グローバル関数;Strideableが優先されます。したがって、上記の同等の Swift 3.0 バージョンは次のようになります。stride(from:through:by:)stride(from:to:by:)

/* Swift 3.0: stride example usage */
let from = 0
let to = 10
let through = 10
let by = 1
for _ in stride(from: from, through: through, by: by) { }
for _ in stride(from: from, to: to, by: by) { }

あなたの例では、ループ内stride(from:through:by:)の不変式が以下forとの比較を使用するため、閉区間ストライド代替を使用したいと考えています( )。いえ<=

/* example values of your parameters 'first', 'last' and 'interval' */
let first = 0
let last = 10
let interval = 2
var n = 0
for f in stride(from: first, through: last, by: interval) { 
    print(f)
    n += 1 
} // 0 2 4 6 8 10
print(n) // 6

当然のことながら、ループをループから へforの通過の例としてのみ使用します。特定の例では、ループを必要とせずに計算するだけです ( )。forstridenn=1+(last-first)/interval

strideSwift 3.0:より複雑な反復インクリメント ロジックの代替

進化提案 SE-0094 の実装により、Swift 3.0 はグローバルsequence関数を導入しました。

これは、より複雑な反復インクリメント リレーションを使用する場合の適切な代替手段となる可能性がありますstride(この例ではそうではありません)。

宣言

func sequence<T>(first: T, next: @escaping (T) -> T?) -> 
         UnfoldSequence<T, (T?, Bool)>

func sequence<T, State>(state: State, 
                        next: @escaping (inout State) -> T?) ->
           UnfoldSequence<T, State>

これら 2 つの関数のうち、最初の関数について簡単に説明します。next引数は、いくつかのロジックを適用して、現在の要素から次のシーケンス要素を遅延構築するクロージャを取ります ( で始まりますfirst)。が返されるとシーケンスは終了し、nextが返されないnil場合は無限になります。nextnil

上記の単純な定数ストライドの例に適用すると、この方法は少し冗長であり、この目的に適したソリューションsequenceに関してはやり過ぎです。stride

let first = 0
let last = 10
let interval = 2
var n = 0
for f in sequence(first: first,
                  next: { $0 + interval <= last ? $0 + interval : nil }) {
    print(f)
    n += 1
} // 0 2 4 6 8 10
print(n) // 6

sequenceただし、ストライドが一定でない場合、たとえば次の Q&A で説明されている例のように、関数は非常に役立ちます。

最終的なnilリターンでシーケンスを終了するように注意してください (そうでない場合: 「無限の」要素生成)。または、Swift 3.1 が到着したらprefix(while:)、進化の提案SE-で説明されているように、シーケンスのメソッドと組み合わせてその遅延生成を利用します。 0045 . この回答の実行例に適用された後者sequenceは、要素生成の終了基準を明確に含めて、アプローチを冗長にしません。

/* for Swift 3.1 */
// ... as above
for f in sequence(first: first, next: { $0 + interval })
    .prefix(while: { $0 <= last }) {
    print(f)
    n += 1
} // 0 2 4 6 8 10
print(n) // 6
于 2016-05-16T09:20:29.783 に答える
15

簡単に言えば、Swift 3.0 の作業コード:

let (first, last, interval) = (0, 100, 1)
var n = 0
for _ in stride(from: first, to: last, by: interval) {
    n += 1
}
于 2017-03-15T19:45:55.073 に答える
-5

for _ in 0.stride(to: last, by: interval) { n += 1 }

于 2016-05-11T18:18:45.233 に答える