Swift programlama dilinde bir dizenin n'inci karakterini edinin


419

Bir dizenin n'inci karakterini nasıl alabilirim? []Hiç şans olmadan braket ( ) erişimci denedim .

var string = "Hello, world!"

var firstChar = string[0] // Throws error

HATA: 'alt simge' kullanılamıyor: bir Int ile Dize abone olamaz, tartışma için belge yorumuna bakın


1
"Dize ile bir Int abonesi olamaz, hata için tartışma belgelerine bakın" hata mesajı github.com/apple/swift/blob/master/stdlib/public/core/…
andrewdotn

kullanmak var firstChar = string.index(string.startIndex, offsetBy: 0)yerine
Sazzad Hissain Khan

@SazzadHissainKhan bu bir karakter değil, bir dize diziniyle sonuçlanır. Neden sadece basit değil string.startIndex? İlk karakter için string[string.startIndex] ya da sadece string.first. İlk önce dizenin boş olup olmadığını kontrol etmeniz gereken ilk yaklaşımın ikincisinin isteğe bağlı olduğunu unutmayın
Leo Dabus

Yanıtlar:


567

Dikkat: Lütfen Leo Dabus'un cevabına bakınız. Swift 4 ve Swift 5 için doğru bir uygulama için bakın.

Swift 4 veya üstü

SubstringTipi en alt simge işlevleri dönmek gerektiğini böylece, altdizgelerin hızlı ve daha verimli orijinal dizeyle depolamayı paylaşarak yapmak Swift 4'te tanıtıldı.

Burada deneyin

extension StringProtocol {
    subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] }
    subscript(range: Range<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: ClosedRange<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: PartialRangeFrom<Int>) -> SubSequence { self[index(startIndex, offsetBy: range.lowerBound)...] }
    subscript(range: PartialRangeThrough<Int>) -> SubSequence { self[...index(startIndex, offsetBy: range.upperBound)] }
    subscript(range: PartialRangeUpTo<Int>) -> SubSequence { self[..<index(startIndex, offsetBy: range.upperBound)] }
}

Dönüştürmek için Substringbir içine String, sadece yapabilirsiniz String(string[0..2]), ancak yalnızca planlıyorsanız etrafında alt dize tutmak için yapmalıyız. Aksi takdirde, a tutmak daha verimlidir Substring.

Birisi bu iki uzantıyı bir araya getirmek için iyi bir yol bulabilirse harika olurdu. StringProtocol Başarısız bir şekilde genişletmeyi denedim , çünkü indexyöntem orada yok. Not: Bu cevap zaten düzenlendi, düzgün bir şekilde uygulandı ve şimdi alt dizeler için de çalışıyor. StringProtocol türünüze abone olurken kilitlenmeyi önlemek için geçerli bir aralık kullandığınızdan emin olun. Aralık dışı değerlerle çökmeyecek bir aralıkta abonelik için bu uygulamayı kullanabilirsiniz


Bu neden yerleşik değil?

Hata mesajı "tartışma için dokümantasyon yorumuna bakın" yazıyor . Apple, UnavailableStringAPIs.swift dosyasında aşağıdaki açıklamayı sağlar :

Tamsayı içeren abonelik dizeleri kullanılamaz.

" iBir karakter dizisindeki inci karakter " kavramı, farklı kütüphanelerde ve sistem bileşenlerinde farklı yorumlara sahiptir. Kullanım durumuna ve ilgili API'lara göre doğru yorum seçilmelidir, bu nedenle String bir tamsayı ile abone olamazsınız.

Swift, dizelerde saklanan karakter verilerine erişmek için birkaç farklı yol sunar.

  • String.utf8dizesindeki UTF-8 kod birimler topluluğudur. Dizeyi UTF-8'e dönüştürürken bu API'yı kullanın. Çoğu POSIX API, dizeleri UTF-8 kod birimleri cinsinden işler.

  • String.utf16dizesinde UTF-16 kod birimlerinin bir koleksiyonudur. Çoğu Kakao ve Kakao dokunma API'leri, dizeleri UTF-16 kod birimleri açısından işler. Örneğin, UTF-16 kod birimleri açısından alt dize ofsetleri ve uzunlukları NSRangeile birlikte kullanılan NSAttributedStringve NSRegularExpressionsaklanan örnekler .

  • String.unicodeScalarsUnicode skaler koleksiyonudur. Karakter verilerinin düşük düzeyde manipülasyonunu yaparken bu API'yı kullanın.

  • String.characters kullanıcı tarafından algılanan karakterlerin bir tahmini olan genişletilmiş grafik kümeleri topluluğudur.

İnsan tarafından okunabilir metin içeren dizeleri işlerken, karakter karakter işlemeden mümkün olduğunca kaçınılması gerektiğini unutmayın. Kullanım üst düzey yerel duyarlı Unicode algoritmaları yerine, örneğin, String.localizedStandardCompare(), String.localizedLowercaseString, String.localizedStandardRangeOfString()vb


4
Cannot find an overload for 'advance' that accepts an argument list of type '(String.Index, T)'... String.Indexve Intuyumlu değil.

7
Cannot subscript a value of type 'String'...Bu yanıtı kontrol ederseniz : stackoverflow.com/a/31265316/649379
SoftDesigner

24
Bunu kullanmaya çalıştığımda anladım Ambiguous use of 'subscript'.
jowie

18
UYARI! Aşağıdaki uzantı korkunç derecede verimsiz. Bir dizeye bir tamsayı ile her erişildiğinde, başlangıç ​​dizinini ilerletmek için bir O (n) işlevi çalıştırılır. Doğrusal bir döngüyü başka bir doğrusal döngünün içine çalıştırmak, döngünün yanlışlıkla O (n2) olduğu anlamına gelir - dizginin uzunluğu arttıkça, bu döngünün kuadratik olarak arttığı süre. Bunu yapmak yerine karakterlerin dize koleksiyonunu kullanabilirsiniz.
ignaciohugog

2
fatal error: Can't form a Character from an empty String
Devin B

341

Hızlı 5.2

let str = "abcdef"
str[1 ..< 3] // returns "bc"
str[5] // returns "f"
str[80] // returns ""
str.substring(fromIndex: 3) // returns "def"
str.substring(toIndex: str.length - 2) // returns "abcd"

Bu String uzantısını projenize eklemeniz gerekir (tamamen test edilmiştir):

extension String {

    var length: Int {
        return count
    }

    subscript (i: Int) -> String {
        return self[i ..< i + 1]
    }

    func substring(fromIndex: Int) -> String {
        return self[min(fromIndex, length) ..< length]
    }

    func substring(toIndex: Int) -> String {
        return self[0 ..< max(0, toIndex)]
    }

    subscript (r: Range<Int>) -> String {
        let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
                                            upper: min(length, max(0, r.upperBound))))
        let start = index(startIndex, offsetBy: range.lowerBound)
        let end = index(start, offsetBy: range.upperBound - range.lowerBound)
        return String(self[start ..< end])
    }
}

Swift her zaman bu sorunun (aşağıda sağladığım String uzantısı olmadan) kutudan çözümüne sahip olmasa da , uzantıyı kullanmanızı şiddetle tavsiye ederim . Neden? String'in sözdiziminin hemen hemen her sürümü değiştirdiği Swift'in ilk sürümlerinden onlarca saat boyunca acı veren göçümü kurtardığı için, tüm yapmam gereken, tüm projeyi yeniden düzenlemenin aksine uzantının uygulamasını güncellemekti. Seçimini yap.

let str = "Hello, world!"
let index = str.index(str.startIndex, offsetBy: 4)
str[index] // returns Character 'o'

let endIndex = str.index(str.endIndex, offsetBy:-2)
str[index ..< endIndex] // returns String "o, worl"

String(str.suffix(from: index)) // returns String "o, world!"
String(str.prefix(upTo: index)) // returns String "Hell"

değişim range.upperBound - range.lowerBoundiçinrange.count
Leo Dabus

Bu asıl sorunun bir parçası değil, ama ... bu ödevin desteklenmesi de iyi olurdu. Örneğin, s [i] = "a" :).
Chris Prince

2
Swift 4.2 aboneliklerinin tekrar kullanılamayacağına inanıyorum. Bir hata
mesajı

2
@ChrisPrinceextension StringProtocol where Self: RangeReplaceableCollection { subscript(offset: Int) -> Element { get { return self[index(startIndex, offsetBy: offset)] } set { let start = index(startIndex, offsetBy: offset) replaceSubrange(start..<index(after: start), with: [newValue]) } } }
Leo Dabus

Bu yerleşik işlevler olmalıdır
Ammar Mujeeb

150

Bu düzgün geçici çözümü buldum

var firstChar = Array(string)[0]

2
Bu, UTF8 veya ASCII kodlu dizeleriniz olduğunu bildiğiniz (yaygın) durum için iyi bir hızlı çözümdür. Dizelerin asla birden fazla bayt kullanan bir kodlamada olmayacağından emin olun.
Jeff Hay

48
Sadece ilk karakteri elde etmek için tüm dizeyi kopyalarken bu son derece verimsiz görünüyor. String [string] kullanın. startIndex], Sulthan'ın işaret ettiği gibi 0 yerine.
Bjorn

6
Dize paketini açın: var firstChar = Array(string!)[0]Aksi takdirde söyleyecektiradd arrayLiteral
Mohammad Zaid Pathan

2
Bunun temiz olduğuna inanmıyorum, aslında bir tur. Bu ilk neden Array hangi başlatıcı kullanılır emin değilim (ve dizi için ayrı bileşenler olarak dizenin karakterleri toplamak için neden SequenceType başlatıcısı olduğunu varsayalım). Bu hiç de açık değildir ve gelecekte tür dökümü olmadan düzeltilebilir. [String] .first dizisi için kısayol kullanırsanız bu da çalışmaz. @ Sulthan'ın çözümü en iyi sonucu, pişirilmiş indeks değerlerini kullanmak için kullanır. Burada neler olduğu çok daha açık.
TheCodingArt

2
Wow, derleyici segmenti hatası!
Frank

124

Tamsayılar kullanılarak endeksleme yapılmaz, sadece kullanılır String.Index. Çoğunlukla doğrusal karmaşıklıkla. Ayrıca String.Indexbunlardan aralıklar oluşturabilir ve bunları kullanarak alt dizeler alabilirsiniz.

Swift 3.0

let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.index(before: someString.endIndex)]
let charAtIndex = someString[someString.index(someString.startIndex, offsetBy: 10)]

let range = someString.startIndex..<someString.index(someString.startIndex, offsetBy: 10)
let substring = someString[range]

Swift 2.x

let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.endIndex.predecessor()]
let charAtIndex = someString[someString.startIndex.advanceBy(10)]

let range = someString.startIndex..<someString.startIndex.advanceBy(10)
let subtring = someString[range]

Bir dizeden başka bir dizeye oluşturulan bir dizini (veya aralığı) asla kullanamayacağınızı unutmayın

let index10 = someString.startIndex.advanceBy(10)

//will compile
//sometimes it will work but sometimes it will crash or result in undefined behaviour
let charFromAnotherString = anotherString[index10]

7
Stringdizinler bir dizeye özgüdür. Bunun nedeni, farklı dizelerin farklı çok birimli UTF-16'ya Charactersve / veya farklı konumlara sahip olabilmesidir, bu nedenle UTF-16 birim dizinleri eşleşmez, bir çok birimli UTF-16'nın sonunun veya noktasının ötesine düşebilir Character.
zaph

@Zaph Bu çok açık.
Sulthan

3
Neden söylediğini açıklamak: "bazen çökebilir veya tanımsız davranışa neden olabilir". Belki daha iyi söyleme daha iyi çünkü ...
zaph

1
@Sulthan ..şimdi ..<(görevinizde range)
Aaron Brager

3
@CajunLuke Bu yorumu yayınladığınızdan beri biraz zaman geçtiğini biliyorum, ancak bu cevaba bir göz atın . Kullanabilirsinizvar lastChar = string[string.endIndex.predecessor()]
David L

122

Xcode 11 • Hızlı 5.1

Alt betiğin alt dizelerde de kullanılabilmesi için StringProtocol öğesini genişletebilirsiniz:

extension StringProtocol {
    subscript(_ offset: Int)                     -> Element     { self[index(startIndex, offsetBy: offset)] }
    subscript(_ range: Range<Int>)               -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
    subscript(_ range: ClosedRange<Int>)         -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
    subscript(_ range: PartialRangeThrough<Int>) -> SubSequence { prefix(range.upperBound.advanced(by: 1)) }
    subscript(_ range: PartialRangeUpTo<Int>)    -> SubSequence { prefix(range.upperBound) }
    subscript(_ range: PartialRangeFrom<Int>)    -> SubSequence { suffix(Swift.max(0, count-range.lowerBound)) }
}

extension LosslessStringConvertible {
    var string: String { .init(self) }
}

extension BidirectionalCollection {
    subscript(safe offset: Int) -> Element? {
        guard !isEmpty, let i = index(startIndex, offsetBy: offset, limitedBy: index(before: endIndex)) else { return nil }
        return self[i]
    }
}

Test yapmak

let test = "Hello USA 🇺🇸!!! Hello Brazil 🇧🇷!!!"
test[safe: 10]   // "🇺🇸"
test[11]   // "!"
test[10...]   // "🇺🇸!!! Hello Brazil 🇧🇷!!!"
test[10..<12]   // "🇺🇸!"
test[10...12]   // "🇺🇸!!"
test[...10]   // "Hello USA 🇺🇸"
test[..<10]   // "Hello USA "
test.first   // "H"
test.last    // "!"

// Subscripting the Substring
 test[...][...3]  // "Hell"

// Note that they all return a Substring of the original String.
// To create a new String from a substring
test[10...].string  // "🇺🇸!!! Hello Brazil 🇧🇷!!!"

"Self [index (startIndex, offsetBy: i)]" nedir diye sorabilir miyim? Ve "ben [i]" nasıl çalışır?
allenlinli

1
Merhaba Leo, çözüm için teşekkürler! Sadece (bugün) Swift 2.3'ten 3'e geçtim ve çözüm aboneliğiniz (aralık: <Int>) "Ekstra argüman 'sınırlıBy' çağrıda" hatası veriyor. Sizce neyin yanlış olabilir?
Ahmet Akkök

@ AhmetAkkök kodu değiştirmediğinizden emin misiniz?
Leo Dabus

1
@Leo, tüm projeyi dönüştürmedim, ancak uygulamada uzantı değil, hem uygulama hem de uzantı için işlemi tekrarladım ve şimdi Tamam çalışıyor. Yardımınız çok takdir ediliyor!
Ahmet Akkök

bu çok karmaşık bir kod. return String(Array(characters)[range])Swift 3'te yapmanın avantajı nedir ?
Dan Rosenstark

69

Hızlı 4

let str = "My String"

Dizindeki dize

let index = str.index(str.startIndex, offsetBy: 3)
String(str[index])    // "S"

substring

let startIndex = str.index(str.startIndex, offsetBy: 3)
let endIndex = str.index(str.startIndex, offsetBy: 7)
String(str[startIndex...endIndex])     // "Strin"

İlk karakter sayısı

let startIndex = str.index(str.startIndex, offsetBy: 3)
String(str[..<startIndex])    // "My "

Son karakter sayısı

let startIndex = str.index(str.startIndex, offsetBy: 3)
String(str[startIndex...])    // "String"

Swift 2 ve 3

str = "My String"

** Dizinde Dize **

Hızlı 2

let charAtIndex = String(str[str.startIndex.advancedBy(3)])  // charAtIndex = "S"

Hızlı 3

str[str.index(str.startIndex, offsetBy: 3)]

İndeks'ten İndeks'e Alt Dizgi

Hızlı 2

let subStr = str[str.startIndex.advancedBy(3)...str.startIndex.advancedBy(7)] // subStr = "Strin"

Hızlı 3

str[str.index(str.startIndex, offsetBy: 3)...str.index(str.startIndex, offsetBy: 7)]

İlk karakter sayısı

let first2Chars = String(str.characters.prefix(2)) // first2Chars = "My"

Son karakter sayısı

let last3Chars = String(str.characters.suffix(3)) // last3Chars = "ing"

24

Xcode 7 GM Tohumundan Swift 2.0

var text = "Hello, world!"

let firstChar = text[text.startIndex.advancedBy(0)] // "H"

N'inci karakter için 0 yerine n-1 girin.

Düzenleme: Swift 3.0

text[text.index(text.startIndex, offsetBy: 0)]


nb dizede belirli karakterleri yakalamanın daha basit yolları var

Örneğin let firstChar = text.characters.first


23

Eğer görürseniz Cannot subscript a value of type 'String'...bu uzantıyı kullanmak:

Hızlı 3

extension String {
    subscript (i: Int) -> Character {
        return self[self.characters.index(self.startIndex, offsetBy: i)]
    }

    subscript (i: Int) -> String {
        return String(self[i] as Character)
    }

    subscript (r: Range<Int>) -> String {
        let start = index(startIndex, offsetBy: r.lowerBound)
        let end = index(startIndex, offsetBy: r.upperBound)
        return self[start..<end]
    }

    subscript (r: ClosedRange<Int>) -> String {
        let start = index(startIndex, offsetBy: r.lowerBound)
        let end = index(startIndex, offsetBy: r.upperBound)
        return self[start...end]
    }
}

Hızlı 2.3

extension String {
    subscript(integerIndex: Int) -> Character {
        let index = advance(startIndex, integerIndex)
        return self[index]
    }

    subscript(integerRange: Range<Int>) -> String {
        let start = advance(startIndex, integerRange.startIndex)
        let end = advance(startIndex, integerRange.endIndex)
        let range = start..<end
        return self[range]
    }
}

Kaynak: http://oleb.net/blog/2014/07/swift-strings/


19

Swift 2.2 Çözümü:

Aşağıdaki uzantı Xcode 7'de çalışır, bu bu çözüm ve Swift 2.0 sözdizimi dönüşümünün bir kombinasyonudur .

extension String {
    subscript(integerIndex: Int) -> Character {
        let index = startIndex.advancedBy(integerIndex)
        return self[index]
    }

    subscript(integerRange: Range<Int>) -> String {
        let start = startIndex.advancedBy(integerRange.startIndex)
        let end = startIndex.advancedBy(integerRange.endIndex)
        let range = start..<end
        return self[range]
    }
}

14

Swift string sınıfı, UTF karakterleri için yerel desteği nedeniyle belirli bir dizinde karakter elde etme yeteneği sağlamaz. Hafızadaki UTF karakterinin değişken uzunluğu doğrudan bir karaktere atlamayı imkansız hale getirir. Bu, her seferinde dizeyi manuel olarak döngüye almanız gerektiği anlamına gelir.

İstediğiniz dizine kadar karakterler arasında döngü oluşturacak bir yöntem sağlamak için String'i genişletebilirsiniz.

extension String {
    func characterAtIndex(index: Int) -> Character? {
        var cur = 0
        for char in self {
            if cur == index {
                return char
            }
            cur++
        }
        return nil
    }
}

myString.characterAtIndex(0)!

3
Zaten dizeler arasında geçiş yapabilirsiniz: "foo" içindeki harf için {println (letter)}
Doobeh

@Doobeh Yukarıdaki düzenlememdeki gibi gerçek karakteri döndürmek ve döndürmek istedim
drewag

Güzel! Bunu nasıl tekrarlayabileceğiniz komik, ama bir indeks yoluyla değil. Swift pitonik hissediyor ama daha sert kenarları var.
Doobeh

Karakterin Int değerini myString.bridgeToObjectiveC().characterAtIndex(0)veya (string as NSString ).characterAtIndex(0)değerini kullanarak buldum
markhunte

4
Do not kullanmak NSStringbir Swift-yerli bireysel karakterleri erişim metotlarını Stringdaha yüksek Unicode karakterleri ile öngörülemeyen sonuçları alırsınız, iki kullanım farklı sayma mekanizmaları -. İlk yöntem güvenli olmalıdır (Swift'in Unicode hataları işlendikten sonra).
Nate Cook

11

Bir kenara not olarak, bir String'in Karakter zinciri temsiline doğrudan uygulanabilen birkaç fonksiyon vardır, örneğin:

var string = "Hello, playground"
let firstCharacter = string.characters.first // returns "H"
let lastCharacter = string.characters.last // returns "d"

Sonuç, Karakter türündedir, ancak bir Dizeye yayınlayabilirsiniz.

Veya bu:

let reversedString = String(string.characters.reverse())
// returns "dnuorgyalp ,olleH" 

:-)


11

Hızlı 4

String(Array(stringToIndex)[index]) 

Muhtemelen bu sorunu bir kerede çözmenin en iyi yolu budur. Muhtemelen String'i önce dizi olarak ve ardından sonucu tekrar String olarak atamak istersiniz. Aksi takdirde, Dize yerine bir Karakter döndürülür.

Örnek String(Array("HelloThere")[1])"e" yi bir String olarak döndürür.

(Array("HelloThere")[1] "e" karakterini Karakter olarak döndürür.

Swift, Dizelerin diziler gibi dizine eklenmesine izin vermez, ancak bu işi kaba kuvvet tarzı yapar.


1
Dize içeriğinin tamamını başka bir bellek konumuna çoğaltmak, özellikle büyük dizeler için ters performans gösterir. Doğrudan bellek erişimi gibi basit görevler için fazladan bellek ayırmaya ihtiyacımız olmamalıdır.
Cristik

7

Çok basit çözümüm:

Hızlı 4.1:

let myString = "Test string"
let index = 0
let firstCharacter = myString[String.Index(encodedOffset: index)]

Hızlı 5.1:

let firstCharacter = myString[String.Index.init(utf16Offset: index, in: myString)]

Swift 4.1'de çalışıyor
leanne

En basit çözüm ve şimdi Swift 5 örneği ile :)
OhadM

@Linh Dao encodedOffset kullanmayın. encodedOffset kullanımdan kaldırıldı: En yaygın kullanım yanlış olduğundan encodedOffset kullanımdan kaldırıldı.
Leo Dabus

@OhadM basit, doğru olduğu anlamına gelmez ya da en azından beklediğiniz gibi çalışmaz Trylet flags = "🇺🇸🇧🇷" flags[String.Index(utf16Offset: 4, in: flags)] // "🇧🇷"
Leo Dabus

1
@OhadM Yorumum sadece bir uyarıydı. Beklediğiniz gibi davrandığını düşünüyorsanız, kullanmaktan çekinmeyin.
Leo Dabus

6

String'i Array'a dönüştürerek ve aşağıdaki gibi alt simge kullanarak belirli bir dizine göre yapabilirsiniz

var str = "Hello"
let s = Array(str)[2]
print(s)

1
Bu çözümün içerik çoğaltmasıyla sonuçlanacağını ve bellek açısından daha düşük ve CPU açısından daha az performans sağlayacağını unutmayın.
Cristik

5

Sadece aynı sorunu yaşadım. Sadece bunu yapın:

var aString: String = "test"
var aChar:unichar = (aString as NSString).characterAtIndex(0)

Bu birçok Emoji ve aslında bir kez birden fazla "karakter" kadar alan diğer karakterler için başarısız NSString.
rmaddy

5

swift3

Belirli bir Dize dizinindeki Karakter'e erişmek için alt simge sözdizimini kullanabilirsiniz.

let greeting = "Guten Tag!"
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index] // a

Https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html adresini ziyaret edin.

veya Swift 4'te bir String Uzantısı yapabiliriz

extension String {
    func getCharAtIndex(_ index: Int) -> Character {
        return self[self.index(self.startIndex, offsetBy: index)]
    }
}

KULLANIM:

let foo = "ABC123"
foo.getCharAtIndex(2) //C

3

Benim çözümüm tek satırda, diyelim ki cadena dize ve 4 istediğiniz konumdur:

let character = cadena[advance(cadena.startIndex, 4)]

Basit ... Sanırım Swift gelecek sürümlerde alt dizeler hakkında daha fazla şey içerecek.


1
Bu var charAtIndex = string[advance(string.startIndex, 10)]Sulthan'ın cevabı ile aynı değil mi?
Martin R

Evet, Sulthan'ın dediği gibi başka bir örnekle aynı çözüm. Kopya için özür dilerim. :) İki kişinin aynı şekilde bulması kolay.
Julio César Fernández Muñoz

3

Swift 3: Başka bir çözüm (oyun alanında test edildi)

extension String {
    func substr(_ start:Int, length:Int=0) -> String? {
        guard start > -1 else {
            return nil
        }

        let count = self.characters.count - 1

        guard start <= count else {
            return nil
        }

        let startOffset = max(0, start)
        let endOffset = length > 0 ? min(count, startOffset + length - 1) : count

        return self[self.index(self.startIndex, offsetBy: startOffset)...self.index(self.startIndex, offsetBy: endOffset)]
    }
}

Kullanımı:

let txt = "12345"

txt.substr(-1) //nil
txt.substr(0) //"12345"
txt.substr(0, length: 0) //"12345"
txt.substr(1) //"2345"
txt.substr(2) //"345"
txt.substr(3) //"45"
txt.substr(4) //"5"
txt.substr(6) //nil
txt.substr(0, length: 1) //"1"
txt.substr(1, length: 1) //"2"
txt.substr(2, length: 1) //"3"
txt.substr(3, length: 1) //"4"
txt.substr(3, length: 2) //"45"
txt.substr(3, length: 3) //"45"
txt.substr(4, length: 1) //"5"
txt.substr(4, length: 2) //"5"
txt.substr(5, length: 1) //nil
txt.substr(5, length: -1) //nil
txt.substr(-1, length: -1) //nil

2

Swift 2.0 subString için güncelleme

public extension String {
    public subscript (i: Int) -> String {
        return self.substringWithRange(self.startIndex..<self.startIndex.advancedBy(i + 1))
    }

    public subscript (r: Range<Int>) -> String {
        get {
            return self.substringWithRange(self.startIndex.advancedBy(r.startIndex)..<self.startIndex.advancedBy(r.endIndex))
        }
    }

}

2

İlk karakteri almak için hızlı bir cevap olabileceğini düşünüyorum:

let firstCharacter = aString[aString.startIndex]

Şundan çok daha zarif ve performans:

let firstCharacter = Array(aString.characters).first

Ama .. Eğer manipüle etmek ve dizelerle daha fazla işlem yapmak istiyorsanız, bir uzantı oluşturmayı düşünebilirsiniz ... Bu yaklaşımla bir uzantı var, burada zaten yayınlanmış olana oldukça benzer:

extension String {
var length : Int {
    return self.characters.count
}

subscript(integerIndex: Int) -> Character {
    let index = startIndex.advancedBy(integerIndex)
    return self[index]
}

subscript(integerRange: Range<Int>) -> String {
    let start = startIndex.advancedBy(integerRange.startIndex)
    let end = startIndex.advancedBy(integerRange.endIndex)
    let range = start..<end
    return self[range]
}

}

AMA KORKUNÇ BİR FİKİR !!

Aşağıdaki uzantı korkunç derecede verimsiz. Bir dizgiye bir tamsayı ile her erişildiğinde, başlangıç ​​dizinini ilerletmek için bir O (n) işlevi çalıştırılır. Doğrusal bir döngüyü başka bir doğrusal döngünün içine çalıştırmak, döngünün kazara O (n2) olduğu anlamına gelir - dizginin uzunluğu arttıkça, bu döngünün kuadratik olarak arttığı süre.

Bunu yapmak yerine karakterlerin dize koleksiyonunu kullanabilirsiniz.


2

Hızlı 3

extension String {

    public func charAt(_ i: Int) -> Character {
        return self[self.characters.index(self.startIndex, offsetBy: i)]
    }

    public subscript (i: Int) -> String {
        return String(self.charAt(i) as Character)
    }

    public subscript (r: Range<Int>) -> String {
        return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
    }

    public subscript (r: CountableClosedRange<Int>) -> String {
        return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
    }

}

kullanım

let str = "Hello World"
let sub = str[0...4]

Yararlı Programlama İpuçları ve Püf Noktaları


2

Aboneliği Al ve Ayarla (String & Substring) - Swift 4.2

Swift 4.2, Xcode 10

Cevabımı @alecarlson'ın cevabına dayandırdım . Tek büyük fark, bir Substringveya bir Stringgeri (ve bazı durumlarda tek bir Character) alabilirsiniz. Ayrıca getve setaboneliği de yapabilirsiniz . Son olarak, benimki @alecarlson'ın cevabından biraz daha hantal ve daha uzun ve bu nedenle, onu bir kaynak dosyaya koymanızı öneririm.


Uzantı:

public extension String {
    public subscript (i: Int) -> Character {
        get {
            return self[index(startIndex, offsetBy: i)]
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
    public subscript (bounds: CountableRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ..< end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeThrough<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ... end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ..< end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }

    public subscript (i: Int) -> String {
        get {
            return "\(self[index(startIndex, offsetBy: i)])"
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            self.replaceSubrange(n...n, with: "\(c)")
        }
    }
    public subscript (bounds: CountableRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ..< end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeThrough<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ... end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ..< end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }

    public subscript (i: Int) -> Substring {
        get {
            return Substring("\(self[index(startIndex, offsetBy: i)])")
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
}
public extension Substring {
    public subscript (i: Int) -> Character {
        get {
            return self[index(startIndex, offsetBy: i)]
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }

    }
    public subscript (bounds: CountableRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ..< end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: PartialRangeThrough<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ... end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ..< end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }
    public subscript (i: Int) -> String {
        get {
            return "\(self[index(startIndex, offsetBy: i)])"
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
    public subscript (bounds: CountableRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ..< end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeThrough<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ... end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ..< end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }

    public subscript (i: Int) -> Substring {
        get {
            return Substring("\(self[index(startIndex, offsetBy: i)])")
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
}

Bu gereksiz bir şekilde her iki dizini de (başlangıç ​​ve bitiş) startIndex'ten öteler. Aralık dizinini kullanarak bitiş dizinini dengeleyebilir ve başlangıç ​​dizinini dengeleyebilirsiniz
Leo Dabus

2

Hızlı 4.2

Bu cevap idealdir çünkü Stringtüm uzantılarını Subsequences( Substring) tek bir uzantıda genişletir

public extension StringProtocol {

    public subscript (i: Int) -> Element {
        return self[index(startIndex, offsetBy: i)]
    }

    public subscript (bounds: CountableClosedRange<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[start...end]
    }

    public subscript (bounds: CountableRange<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[start..<end]
    }

    public subscript (bounds: PartialRangeUpTo<Int>) -> SubSequence {
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[startIndex..<end]
    }

    public subscript (bounds: PartialRangeThrough<Int>) -> SubSequence {
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[startIndex...end]
    }

    public subscript (bounds: CountablePartialRangeFrom<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        return self[start..<endIndex]
    }
}

kullanım

var str = "Hello, playground"

print(str[5...][...5][0])
// Prints ","

Bu gereksiz yere her iki dizini ( startve end) dengeler startIndex. Sadece biraz hafifletebilir endrange.count kullanarak indeksi ve ofset startendeksi
Leo Dabus

2

Şimdiye kadar, alt simge (_ :) kullanılamıyor. Bunu yapamadığımız gibi

str[0] 

"String.Index" sağlamak zorundayız Ama kendi dizin numaramızı bu şekilde nasıl verebiliriz, bunun yerine kullanabiliriz,

string[str.index(str.startIndex, offsetBy: 0)]

Lütfen yanıtınızı düzenleyin ve yalnızca kod yanıtı göndermek yerine yanıtınızın sorunu nasıl çözdüğünü açıklayarak bir bağlam ekleyin. Şu kaynaktan
Pedram Parsian

Neden gereksiz dengelemeyi yapıyorsunuz? Neden basit değil string[string.startIndex]? BTW, iki farklı değişken adı kullandığınız için kod doğru davranmaz / derlenmez.
Cristik

2

Swift 4.2 veya üstü

Sınıf ve kısmi aralığı Altsimgeleme kullanarak String'in indicesözelliği

Varyasyonuna olarak @LeoDabus güzel cevap , biz ek bir uzantı ekleyebilir DefaultIndicesbize geri düşmek mümkün kılması amacıyla indicesmülkiyet String(tarafından özel alt simgeler uygularken Intikincisi için özelleşmiş aralıkları ve kısmi aralıkları).

extension DefaultIndices {
    subscript(at: Int) -> Elements.Index { index(startIndex, offsetBy: at) }
}

// Moving the index(_:offsetBy:) to an extension yields slightly
// briefer implementations for these String extensions.
extension String {
    subscript(range: Range<Int>) -> SubSequence {
        let start = indices[range.lowerBound]
        return self[start..<indices[start...][range.count]]
    }
    subscript(range: ClosedRange<Int>) -> SubSequence {
        let start = indices[range.lowerBound]
        return self[start...indices[start...][range.count]]
    }
    subscript(range: PartialRangeFrom<Int>) -> SubSequence {
        self[indices[range.lowerBound]...]
    }
    subscript(range: PartialRangeThrough<Int>) -> SubSequence {
        self[...indices[range.upperBound]]
    }
    subscript(range: PartialRangeUpTo<Int>) -> SubSequence {
        self[..<indices[range.upperBound]]
    }
}

let str = "foo bar baz bax"
print(str[4..<6]) // "ba"
print(str[4...6]) // "bar"
print(str[4...])  // "bar baz bax"
print(str[...6])  // "foo bar"
print(str[..<6])  // "foo ba"

@LeoDabus, indicesözelliği Stringaboneliğe (diğer) alternatif olarak kullanma yönünde işaret ettiğin için teşekkürler !


1
tek dezavantajı
CountableClosedRange

1
@LeoDabus anlıyorum. Evet çoğunlukla linux ama çok fazla değil Bu günlerde Swift: / Yaptığımda kullanıyorum swiftenv, ancak sanırım kısa bir süre sonra 4.2 ile güncellenecek.
dfri

1
@LeoDabus bu cevabı modern Swift'e güncellediğiniz için teşekkürler!
dfri

1
@LeoDabus güzel iş! Daha sonra ayrıntılara bakmak zorunda kalacak, ama bazı temel / sipariş edilebilir set türlerinin Vakfına geri dönmek zorunda kaldığımızı asla hatırlamıyorum.
dfri

1
sağol kanka!!!
Leo Dabus

2

Hızlı 5.1.3:

Dize uzantısı ekleyin:

extension String {

 func stringAt(_ i: Int) -> String { 
   return String(Array(self)[i]) 
 } 

 func charAt(_ i: Int) -> Character { 
  return Array(self)[i] 
 } 
}

let str = "Teja Kumar"
let str1: String = str.stringAt(2)  //"j"
let str2: Character = str.charAt(5)  //"k"

1
Bu, bu özelliği her çağırdığınızda tüm karakter dizisine bir karakter dizisine dönüştürür.
Leo Dabus

1

Swift'in Stringtürü, characterAtIndexbir Unicode dizesinin kodlanmasının birkaç yolu olduğundan bir yöntem sağlamaz . UTF8, UTF16 veya başka bir şeyle mi gidiyorsunuz?

CodeUnitKoleksiyonlara String.utf8ve String.utf16özelliklerini alarak erişebilirsiniz . Ayrıca erişebilir UnicodeScalaralarak koleksiyonunuString.unicodeScalars özelliği .

Uygulamasının ruhu içinde NSStringbir unichartür döndürüyorum .

extension String
{
    func characterAtIndex(index:Int) -> unichar
    {
        return self.utf16[index]
    }

    // Allows us to use String[index] notation
    subscript(index:Int) -> unichar
    {
        return characterAtIndex(index)
    }
}

let text = "Hello Swift!"
let firstChar = text[0]

Bu, 16 bit'ten daha fazla depolama alanına ihtiyaç duyan karakterler için başarısız olur. Temel olarak, U + FFFF'nin ötesindeki herhangi bir Unicode karakteri.
rmaddy

1

Konuyu beslemek ve hızlı abonelik olanaklarını göstermek için, küçük bir dize "alt dize-araç kutusu" alt simge tabanlı

Bu yöntemler güvenlidir ve hiçbir zaman dize dizinlerinin üzerinden geçmez

extension String {
    // string[i] -> one string char
    subscript(pos: Int) -> String { return String(Array(self)[min(self.length-1,max(0,pos))]) }

    // string[pos,len] -> substring from pos for len chars on the left
    subscript(pos: Int, len: Int) -> String { return self[pos, len, .pos_len, .left2right] }

    // string[pos, len, .right2left] -> substring from pos for len chars on the right
    subscript(pos: Int, len: Int, way: Way) -> String { return self[pos, len, .pos_len, way] }

    // string[range] -> substring form start pos on the left to end pos on the right
    subscript(range: Range<Int>) -> String { return self[range.startIndex, range.endIndex, .start_end, .left2right] }

    // string[range, .right2left] -> substring start pos on the right to end pos on the left
    subscript(range: Range<Int>, way: Way) -> String { return self[range.startIndex, range.endIndex, .start_end, way] }

    var length: Int { return countElements(self) }
    enum Mode { case pos_len, start_end }
    enum Way { case left2right, right2left }
    subscript(var val1: Int, var val2: Int, mode: Mode, way: Way) -> String {
        if mode == .start_end {
            if val1 > val2 { let val=val1 ; val1=val2 ; val2=val }
            val2 = val2-val1
        }
        if way == .left2right {
            val1 = min(self.length-1, max(0,val1))
            val2 = min(self.length-val1, max(1,val2))
        } else {
            let val1_ = val1
            val1 = min(self.length-1, max(0, self.length-val1_-val2 ))
            val2 = max(1, (self.length-1-val1_)-(val1-1) )
        }
        return self.bridgeToObjectiveC().substringWithRange(NSMakeRange(val1, val2))

        //-- Alternative code without bridge --
        //var range: Range<Int> = pos...(pos+len-1)
        //var start = advance(startIndex, range.startIndex)
        //var end = advance(startIndex, range.endIndex)
        //return self.substringWithRange(Range(start: start, end: end))
    }
}


println("0123456789"[3]) // return "3"

println("0123456789"[3,2]) // return "34"

println("0123456789"[3,2,.right2left]) // return "56"

println("0123456789"[5,10,.pos_len,.left2right]) // return "56789"

println("0123456789"[8,120,.pos_len,.right2left]) // return "01"

println("0123456789"[120,120,.pos_len,.left2right]) // return "9"

println("0123456789"[0...4]) // return "01234"

println("0123456789"[0..4]) // return "0123"

println("0123456789"[0...4,.right2left]) // return "56789"

println("0123456789"[4...0,.right2left]) // return "678" << because ??? range can wear endIndex at 0 ???

1

Negatif indeks kullanmanıza izin veren python benzeri bir çözüm,

var str = "Hello world!"
str[-1]        // "!"

olabilirdi:

extension String {
    subscript (var index:Int)->Character{
        get {
            let n = distance(self.startIndex, self.endIndex)
            index %= n
            if index < 0 { index += n }
            return self[advance(startIndex, index)]
        }
    }
}

Bu arada, tüm python'un dilim gösterimini aktarmaya değer


Swift 4 için derleyen bir şey yazmayı düşünür müsünüz? son dönüş ... satır çalışıyor gibi görünüyor advance () işlevi orada inanıyorum.
C0D3

1

Ayrıca String'i aşağıdaki gibi Karakter Dizisine dönüştürebilirsiniz:

let text = "My Text"
let index = 2
let charSequence = text.unicodeScalars.map{ Character($0) }
let char = charSequence[index]

Bu, belirtilen dizinde char'ı sabit zamanda almanın yoludur.

Aşağıdaki örnek sabit zamanda çalışmaz, ancak doğrusal zaman gerektirir. Dizeye göre Dize'de çok fazla arama yapıyorsanız, yukarıdaki yöntemi kullanın.

let char = text[text.startIndex.advancedBy(index)]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.