Swift3で次のように書くにはどうすればよいですか?
for (f = first; f <= last; f += interval)
{
n += 1
}
これは私自身の試みです
for _ in 0.stride(to: last, by: interval)
{
n += 1
}
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
の通過の例としてのみ使用します。特定の例では、ループを必要とせずに計算するだけです ( )。for
stride
n
n=1+(last-first)/interval
stride
Swift 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
場合は無限になります。next
nil
上記の単純な定数ストライドの例に適用すると、この方法は少し冗長であり、この目的に適したソリューション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
簡単に言えば、Swift 3.0 の作業コード:
let (first, last, interval) = (0, 100, 1)
var n = 0
for _ in stride(from: first, to: last, by: interval) {
n += 1
}
for _ in 0.stride(to: last, by: interval) { n += 1 }