Saya ingin mengubah indeks surat yang terkandung dalam string menjadi nilai integer. Mencoba membaca file header tetapi saya tidak dapat menemukan jenisnya Index
, meskipun tampaknya sesuai dengan protokol ForwardIndexType
dengan metode (misalnya distanceTo
).
var letters = "abcdefg"
let index = letters.characters.indexOf("c")!
// ERROR: Cannot invoke initializer for type 'Int' with an argument list of type '(String.CharacterView.Index)'
let intValue = Int(index) // I want the integer value of the index (e.g. 2)
Setiap bantuan dihargai.
let index = letters.characters.index(of: "c")
Baris berikutnyalet int_index = letters.characters.distance(from: letters.startIndex, to: index)
Jawaban:
edit / perbarui:
Xcode 11 β’ Swift 5.1 atau lebih baru
extension StringProtocol { func distance(of element: Element) -> Int? { firstIndex(of: element)?.distance(in: self) } func distance<S: StringProtocol>(of string: S) -> Int? { range(of: string)?.lowerBound.distance(in: self) } }
extension Collection { func distance(to index: Index) -> Int { distance(from: startIndex, to: index) } }
extension String.Index { func distance<S: StringProtocol>(in string: S) -> Int { string.distance(to: self) } }
Pengujian tempat bermain
let letters = "abcdefg" let char: Character = "c" if let distance = letters.distance(of: char) { print("character \(char) was found at position #\(distance)") // "character c was found at position #2\n" } else { print("character \(char) was not found") }
let string = "cde" if let distance = letters.distance(of: string) { print("string \(string) was found at position #\(distance)") // "string cde was found at position #2\n" } else { print("string \(string) was not found") }
sumber
Cepat 4
var str = "abcdefg" let index = str.index(of: "c")?.encodedOffset // Result: 2
Catatan: Jika String berisi beberapa karakter yang sama, itu hanya akan mendapatkan karakter terdekat dari kiri
var str = "abcdefgc" let index = str.index(of: "c")?.encodedOffset // Result: 2
sumber
"πΊπΈπΊπΈπ§π·".index(of: "π§π·")?.encodedOffset // 16
encodedOffset
sudah tidak digunakan lagi dari Swift 4.2 .Pesan penghentian :
encodedOffset
tidak berlaku lagi karena sebagian besar penggunaan umum tidak benar. Gunakanutf16Offset(in:)
untuk mencapai perilaku yang sama.Jadi kita bisa menggunakan
utf16Offset(in:)
seperti ini:var str = "abcdefgc" let index = str.index(of: "c")?.utf16Offset(in: str) // Result: 2
sumber
let str = "πΊπΈπΊπΈπ§π·"
let index = str.firstIndex(of: "π§π·")?.utf16Offset(in: str)
// Hasil: 8Untuk melakukan operasi string berdasarkan indeks, Anda tidak dapat melakukannya dengan pendekatan numerik indeks tradisional. karena swift.index diambil oleh fungsi indeks dan bukan dalam tipe Int. Meskipun String adalah larik karakter, kita tetap tidak bisa membaca elemen demi indeks.
Ini membuat frustasi.
Jadi, untuk membuat substring baru dari setiap karakter string genap, periksa kode di bawah ini.
let mystr = "abcdefghijklmnopqrstuvwxyz" let mystrArray = Array(mystr) let strLength = mystrArray.count var resultStrArray : [Character] = [] var i = 0 while i < strLength { if i % 2 == 0 { resultStrArray.append(mystrArray[i]) } i += 1 } let resultString = String(resultStrArray) print(resultString)
Keluaran: acegikmoqsuwy
Terima kasih sebelumnya
sumber
var counter = 0
let result = mystr.filter { _ in
defer { counter += 1 }
return counter.isMultiple(of: 2)
}
var index = mystr.startIndex
let result = mystr.filter { _ in
defer { mystr.formIndex(after: &index) }
return mystr.distance(from: mystr.startIndex, to: index).isMultiple(of: 2)
}
Berikut adalah ekstensi yang memungkinkan Anda mengakses batas substring sebagai
Int
s, bukanString.Index
nilai:import Foundation /// This extension is available at /// https://gist.github.com/zackdotcomputer/9d83f4d48af7127cd0bea427b4d6d61b extension StringProtocol { /// Access the range of the search string as integer indices /// in the rendered string. /// - NOTE: This is "unsafe" because it may not return what you expect if /// your string contains single symbols formed from multiple scalars. /// - Returns: A `CountableRange<Int>` that will align with the Swift String.Index /// from the result of the standard function range(of:). func countableRange<SearchType: StringProtocol>( of search: SearchType, options: String.CompareOptions = [], range: Range<String.Index>? = nil, locale: Locale? = nil ) -> CountableRange<Int>? { guard let trueRange = self.range(of: search, options: options, range: range, locale: locale) else { return nil } let intStart = self.distance(from: startIndex, to: trueRange.lowerBound) let intEnd = self.distance(from: trueRange.lowerBound, to: trueRange.upperBound) + intStart return Range(uncheckedBounds: (lower: intStart, upper: intEnd)) } }
Sadarilah bahwa ini dapat menyebabkan keanehan, itulah sebabnya Apple memilih untuk membuatnya sulit. (Meskipun itu adalah keputusan desain yang bisa diperdebatkan - menyembunyikan hal yang berbahaya hanya dengan membuatnya sulit ...)
Anda dapat membaca lebih lanjut di dokumentasi String dari Apple , tetapi tldrnya adalah bahwa ini berasal dari fakta bahwa "indeks" ini sebenarnya khusus untuk penerapan. Mereka mewakili indeks ke dalam string setelah dirender oleh OS , dan dengan demikian dapat bergeser dari OS-ke-OS tergantung pada versi apa dari spesifikasi Unicode yang digunakan. Ini berarti bahwa mengakses nilai dengan indeks tidak lagi menjadi operasi waktu konstan, karena spesifikasi UTF harus dijalankan di atas data untuk menentukan tempat yang tepat dalam string. Indeks ini juga tidak akan sejalan dengan nilai yang dihasilkan oleh NSString, jika Anda menjembataninya, atau dengan indeks ke skalar UTF yang mendasarinya. Pengembang peringatan.
sumber
func rangeInt<S: StringProtocol>(of aString: S, options: String.CompareOptions = []) -> Range<Int>? {
guard let range = range(of: aString, options: options) else { return nil }
let start = distance(from: startIndex, to: range.lowerBound)
return start..<start+distance(from: range.lowerBound, to: range.upperBound)
}
countableRange
dan kembaliCountableRange