Ketika saya menggunakan loop untuk di Playground, semuanya bekerja dengan baik, sampai saya mengubah parameter pertama untuk loop menjadi nilai tertinggi. (iterasi dalam urutan menurun)
Apakah ini bug? Apakah ada orang lain yang memilikinya?
for index in 510..509
{
var a = 10
}
Penghitung yang menampilkan jumlah iterasi yang akan dieksekusi terus berdetak ...
ios
swift
swift-playground
Krishnan
sumber
sumber
Jawaban:
Xcode 6 beta 4 menambahkan dua fungsi untuk beralih pada rentang dengan langkah selain satu:,
stride(from: to: by:)
yang digunakan dengan rentang eksklusif danstride(from: through: by:)
, yang digunakan dengan rentang inklusif.Untuk beralih pada rentang dalam urutan terbalik, mereka dapat digunakan seperti di bawah ini:
Perhatikan bahwa keduanya bukan merupakan
Range
fungsi anggota. Mereka adalah fungsi global yang mengembalikan salah satuStrideTo
atau sebuahStrideThrough
struct, yang didefinisikan secara berbeda dariRange
struct.Versi sebelumnya dari jawaban ini menggunakan
by()
fungsi anggotaRange
struct, yang telah dihapus dalam versi beta 4. Jika Anda ingin melihat cara kerjanya, periksa riwayat edit.sumber
5.stride(to: 1, by: -1)
atau5.stride(through: 1, by: -1)
:
operatornya secara implisit berulang ke bawah, menyebabkan loop mereka untuk mengeksekusi ketika mereka berpikir itu akan melompati mereka. Ini sangat nyaman untuk penggunaan interaktif, tetapi sangat rawan kesalahan dalam skrip, ke titik di mana panduan gaya merekomendasikan untuk tidak menggunakannya .Terapkan fungsi terbalik ke rentang untuk beralih mundur:
Untuk Swift 1.2 dan sebelumnya:
Ini juga bekerja dengan rentang setengah terbuka:
Catatan:
reverse(1...10)
membuat larik tipe[Int]
, jadi meskipun ini mungkin baik untuk rentang kecil, akan lebih bijaksana untuk menggunakanlazy
seperti yang ditunjukkan di bawah ini atau mempertimbangkanstride
jawaban yang diterima jika rentang Anda besar.Untuk menghindari membuat array besar, gunakan
lazy
bersamareverse()
. Tes berikut berjalan efisien di Playground yang menunjukkan bahwa itu tidak membuat array dengan satu triliunInt
s!Uji:
Untuk Swift 2.0 di Xcode 7:
Perhatikan bahwa dalam Swift 2.0,
(1...1_000_000_000_000).reverse()
bertipeReverseRandomAccessCollection<(Range<Int>)>
, jadi ini berfungsi dengan baik:For Swift 3.0
reverse()
telah diubah namanya menjadireversed()
:sumber
reversed
dapat menyalin koleksi. Setidaknya, begitulah cara saya memahami dokumentasiData
.Diperbarui untuk Swift 3
Jawaban di bawah ini adalah ringkasan dari opsi yang tersedia. Pilih salah satu yang paling sesuai dengan kebutuhan Anda.
reversed
: angka dalam suatu rentangMeneruskan
Ke belakang
reversed
: elemen dalamSequenceType
Meneruskan
Ke belakang
reversed
: elemen dengan indeksTerkadang indeks diperlukan saat iterasi melalui koleksi. Untuk itu Anda dapat menggunakan
enumerate()
, yang mengembalikan tupel. Elemen pertama dari tuple adalah indeks dan elemen kedua adalah objek.Meneruskan
Ke belakang
Perhatikan bahwa seperti yang dicatat Ben Lachman dalam jawabannya , Anda mungkin ingin melakukan
.enumerated().reversed()
alih - alih.reversed().enumerated()
(yang akan membuat angka indeks meningkat).melangkah: angka
Langkahnya adalah cara untuk beralih tanpa menggunakan rentang. Ada dua bentuk. Komentar di akhir kode menunjukkan seperti apa versi jangkauan (dengan asumsi ukuran kenaikan adalah 1).
Meneruskan
Ke belakang
Mengubah ukuran kenaikan untuk
-1
memungkinkan Anda untuk mundur.Perhatikan
to
danthrough
perbedaan.langkahnya: elemen SequenceType
Maju dengan selisih 2
Saya menggunakan
2
dalam contoh ini hanya untuk menunjukkan kemungkinan lain.Ke belakang
Catatan
@matt memiliki solusi menarik di mana ia mendefinisikan operator baliknya sendiri dan menyebutnya
>>>
. Tidak perlu banyak kode untuk didefinisikan dan digunakan seperti ini:Lihat C-Style Untuk Loops Dihapus dari Swift 3
sumber
Cepat 4 dan seterusnya
sumber
Dengan Swift 5, sesuai dengan kebutuhan Anda, Anda dapat memilih salah satu dari empat contoh kode Playground berikut untuk menyelesaikan masalah Anda.
# 1. Menggunakan
ClosedRange
reversed()
metodeClosedRange
memiliki metode yang disebutreversed()
.reversed()
Metode memiliki deklarasi berikut:Pemakaian:
Sebagai alternatif, Anda dapat menggunakan
Range
reversed()
metode:# 2. Menggunakan
sequence(first:next:)
fungsiSwift Standard Library menyediakan fungsi yang disebut
sequence(first:next:)
.sequence(first:next:)
memiliki deklarasi berikut:Pemakaian:
# 3. Menggunakan
stride(from:through:by:)
fungsiSwift Standard Library menyediakan fungsi yang disebut
stride(from:through:by:)
.stride(from:through:by:)
memiliki deklarasi berikut:Pemakaian:
Sebagai alternatif, Anda dapat menggunakan
stride(from:to:by:)
:# 4 Menggunakan
AnyIterator
init(_:)
inisialisasiAnyIterator
memiliki penginisialisasi yang disebutinit(_:)
.init(_:)
memiliki deklarasi berikut:Pemakaian:
Jika perlu, Anda dapat memperbaiki kode sebelumnya dengan membuat metode ekstensi untuk
Int
dan membungkus iterator Anda di dalamnya:sumber
Untuk Swift 2.0 dan di atasnya, Anda harus menerapkan pembalikan pada koleksi rentang
Ini telah diubah namanya menjadi .reversed () di Swift 3.0
sumber
Dalam Swift 4 dan yang terakhir
sumber
Cepat 4.0
Jika Anda ingin memasukkan
to
nilainya:sumber
Jika seseorang ingin beralih melalui array (
Array
atau lebih umum apa sajaSequenceType
) secara terbalik. Anda memiliki beberapa opsi tambahan.Pertama, Anda dapat
reverse()
array dan loop melalui itu seperti biasa. Namun saya lebih suka menggunakanenumerate()
banyak waktu karena menghasilkan tuple yang berisi objek dan indeksnya.Satu hal yang perlu diperhatikan di sini adalah penting untuk menyebutnya dengan urutan yang benar:
for (index, element) in array.enumerate().reverse()
menghasilkan indeks dalam urutan menurun (yang biasanya saya harapkan). sedangkan:
for (index, element) in array.reverse().enumerate()
(yang merupakan pertandingan yang lebih dekat dengan NSArrayreverseEnumerator
)berjalan array ke belakang tetapi menampilkan indeks naik.
sumber
seperti untuk Swift 2.2, Xcode 7.3 (10, Juni, 2016):
Output:
sumber
Anda dapat mempertimbangkan menggunakan
while
loop C-Style sebagai gantinya. Ini berfungsi dengan baik di Swift 3:sumber
Anda dapat menggunakan metode terbalik () untuk dengan mudah membalikkan nilai.
Metode terbalik () membalikkan nilai.
sumber
sumber