Comment utilisez-vous Ssortingng.subssortingngWithRange? (ou comment les gammes fonctionnent-elles dans Swift?)

Je n’ai pas encore été capable de comprendre comment obtenir une sous-chaîne d’une Ssortingng dans Swift:

 var str = “Hello, playground” func test(str: Ssortingng) -> Ssortingng { return str.subssortingngWithRange( /* What goes here? */ ) } test (str) 

Je ne suis pas capable de créer une gamme dans Swift. La saisie semi-automatique dans le terrain de jeu n’est pas très utile – c’est ce que cela suggère:

 return str.subssortingngWithRange(aRange: Range) 

Je n’ai rien trouvé dans la bibliothèque de référence standard Swift qui aide. Voici une autre conjecture sauvage:

 return str.subssortingngWithRange(Range(0, 1)) 

Et ça:

 let r:Range = Range(start: 0, end: 2) return str.subssortingngWithRange(r) 

J’ai vu d’autres réponses ( Recherche d’index de caractère dans Swift Ssortingng ) qui semblent suggérer que puisque Ssortingng est un type de pont pour NSSsortingng , les “anciennes” méthodes devraient fonctionner, mais on ne sait pas comment – par exemple, cela ne fonctionne pas soit (ne semble pas être une syntaxe valide):

 let x = str.subssortingngWithRange(NSMakeRange(0, 3)) 

Pensées?

Vous pouvez utiliser la méthode subssortingngWithRange. Il prend un début et une fin Ssortingng.Index.

 var str = "Hello, playground" str.subssortingngWithRange(Range(start: str.startIndex, end: str.endIndex)) //"Hello, playground" 

Pour modifier l’index de début et de fin, utilisez advancedBy (n).

 var str = "Hello, playground" str.subssortingngWithRange(Range(start: str.startIndex.advancedBy(2), end: str.endIndex.advancedBy(-1))) //"llo, playgroun" 

Vous pouvez également toujours utiliser la méthode NSSsortingng avec NSRange, mais vous devez vous assurer que vous utilisez un NSSsortingng comme celui-ci:

 let myNSSsortingng = str as NSSsortingng myNSSsortingng.subssortingngWithRange(NSRange(location: 0, length: 3)) 

Remarque: comme mentionné dans JanX2, cette seconde méthode n’est pas sûre avec les chaînes Unicode.

Swift 2

Simple

 let str = "My Ssortingng" let subStr = str[str.startIndex.advancedBy(3)...str.startIndex.advancedBy(7)] //"Ssortingn" 

Swift 3

 let startIndex = str.index(str.startIndex, offsetBy: 3) let endIndex = str.index(str.startIndex, offsetBy: 7) str[startIndex...endIndex] // "Ssortingn" str.subssortingng(to: startIndex) // "My " str.subssortingng(from: startIndex) // "Ssortingng" 

Swift 4

subssortingng(to:) et la subssortingng(from:)subssortingng(from:) sont obsolètes dans Swift 4 .

 Ssortingng(str[.. 

REMARQUE: @airspeedswift présente des points très éclairants sur les compromis de cette approche, en particulier les impacts cachés sur les performances. Les chaînes ne sont pas de simples bêtes, et accéder à un index particulier peut prendre O (n) time, ce qui signifie qu’une boucle utilisant un indice peut être O (n ^ 2). Tu étais prévenu.

Vous avez juste besoin d’append une nouvelle fonction d’ subscript qui prend une plage et utilise advancedBy() pour aller là où vous voulez:

 import Foundation extension Ssortingng { subscript (r: Range) -> Ssortingng { get { let startIndex = self.startIndex.advancedBy(r.startIndex) let endIndex = startIndex.advancedBy(r.endIndex - r.startIndex) return self[Range(start: startIndex, end: endIndex)] } } } var s = "Hello, playground" println(s[0...5]) // ==> "Hello," println(s[0..<5]) // ==> "Hello" 

(Cela devrait certainement faire partie de la langue. Veuillez dupe rdar: // 17158813 )

Pour le plaisir, vous pouvez également append un opérateur + aux index:

 func +(var index: T, var count: Int) -> T { for (; count > 0; --count) { index = index.succ() } return index } s.subssortingngWithRange(s.startIndex+2 .. s.startIndex+5) 

(Je ne sais pas encore si celui-ci doit faire partie de la langue ou non.)

Au moment où j’écris, aucune extension n’est parfaitement compatible avec Swift 3 , alors en voici une qui couvre tous les besoins auxquels je pourrais penser:

 extension Ssortingng { func subssortingng(from: Int?, to: Int?) -> Ssortingng { if let start = from { guard start < self.characters.count else { return "" } } if let end = to { guard end >= 0 else { return "" } } if let start = from, let end = to { guard end - start >= 0 else { return "" } } let startIndex: Ssortingng.Index if let start = from, start >= 0 { startIndex = self.index(self.startIndex, offsetBy: start) } else { startIndex = self.startIndex } let endIndex: Ssortingng.Index if let end = to, end >= 0, end < self.characters.count { endIndex = self.index(self.startIndex, offsetBy: end + 1) } else { endIndex = self.endIndex } return self[startIndex ..< endIndex] } func substring(from: Int) -> Ssortingng { return self.subssortingng(from: from, to: nil) } func subssortingng(to: Int) -> Ssortingng { return self.subssortingng(from: nil, to: to) } func subssortingng(from: Int?, length: Int) -> Ssortingng { guard length > 0 else { return "" } let end: Int if let start = from, start > 0 { end = start + length - 1 } else { end = length - 1 } return self.subssortingng(from: from, to: end) } func subssortingng(length: Int, to: Int?) -> Ssortingng { guard let end = to, end > 0, length > 0 else { return "" } let start: Int if let end = to, end - length > 0 { start = end - length + 1 } else { start = 0 } return self.subssortingng(from: start, to: to) } } 

Et puis, vous pouvez utiliser:

 let ssortingng = "Hello,World!" 

ssortingng.subssortingng(from: 1, to: 7) vous obtient: ello,Wo

ssortingng.subssortingng(to: 7) vous obtient: Hello,Wo

ssortingng.subssortingng(from: 3) vous obtient: lo,World!

ssortingng.subssortingng(from: 1, length: 4) vous obtient: ello

ssortingng.subssortingng(length: 4, to: 7) vous obtient: o,Wo

Mise à jour de la subssortingng(from: Int?, length: Int) pour prendre en charge à partir de zéro.

SWIFT 2.0

simple:

 let mySsortingng = "full text container" let subssortingng = mySsortingng[mySsortingng.startIndex.. 

SWIFT 3.0

 let subssortingng = mySsortingng[mySsortingng.startIndex.. 

SWIFT 4.0

Les opérations de sous-chaîne renvoient une instance du type Subssortingng, au lieu de Ssortingng.

 let subssortingng = mySsortingng[mySsortingng.startIndex.. 

C’est beaucoup plus simple qu’aucune des réponses ici, une fois que vous avez trouvé la bonne syntaxe.

Je veux enlever le [et]

 let mySsortingng = "[ABCDEFGHI]" let startIndex = advance(mySsortingng.startIndex, 1) //advance as much as you like let endIndex = advance(mySsortingng.endIndex, -1) let range = startIndex.. 

Le résultat sera "ABCDEFGHI", le startIndex et le endIndex pourraient également être utilisés dans

 let mySubSsortingng = mySsortingng.subssortingngFromIndex(startIndex) 

etc!

PS: Comme indiqué dans les remarques, il y a des changements de syntaxe dans swift 2 qui vient avec xcode 7 et iOS9!

S'il vous plaît regardez cette page

Par exemple, pour trouver le prénom (jusqu’au premier espace) en mon nom complet:

 let name = "Joris Kluivers" let start = name.startIndex let end = find(name, " ") if end { let firstName = name[start..end!] } else { // no space found } 

start et end sont du type Ssortingng.Index ici et sont utilisés pour créer un Range et utilisé dans l’accesseur d’ Range (si un espace est trouvé dans la chaîne d’origine).

Il est difficile de créer un Ssortingng.Index directement à partir d’une position entière utilisée dans le message d’ouverture. C’est parce que dans mon nom chaque caractère serait de taille égale en octets. Mais les caractères utilisant des accents spéciaux dans d’autres langues auraient pu utiliser plusieurs octets supplémentaires (selon le codage utilisé). Alors, à quel octet cet entier doit-il se référer?

Il est possible de créer un nouveau Ssortingng.Index partir d’un existant à l’aide des méthodes succ et pred qui garantiront que le nombre correct d’octets est ignoré pour atteindre le prochain sharepoint code dans l’encodage. Cependant, dans ce cas, il est plus facile de rechercher l’index du premier espace dans la chaîne pour trouver l’index de fin.

Puisque Ssortingng est un type de pont pour NSSsortingng, les “anciennes” méthodes devraient fonctionner, mais on ne sait pas comment – par exemple, cela ne fonctionne pas non plus (la syntaxe ne semble pas être valide):

  let x = str.subssortingngWithRange(NSMakeRange(0, 3)) 

Pour moi, c’est la partie vraiment intéressante de votre question. Ssortingng est ponté sur NSSsortingng, de sorte que la plupart des méthodes NSSsortingng fonctionnent directement sur une chaîne. Vous pouvez les utiliser librement et sans réfléchir. Ainsi, par exemple, cela fonctionne exactement comme prévu:

 // delete all spaces from Swift Ssortingng stateName stateName = stateName.ssortingngByReplacingOccurrencesOfSsortingng(" ", withSsortingng:"") 

Mais, comme cela arrive si souvent, “j’ai travaillé mon mojo, mais ça ne marche pas sur vous”. Vous venez de choisir l’un des rares cas où une méthode parallèle nommée Swift existe et, dans un cas comme celui-ci, la méthode Swift éclipse la méthode Objective-C. Ainsi, quand vous dites str.subssortingngWithRange , Swift pense que vous parlez de la méthode Swift plutôt que de la méthode NSSsortingng – et puis vous êtes arraché, car la méthode Swift attend une Range , et vous ne savez pas comment l’un de ces.

La solution la plus simple est d’empêcher Swift d’éclipser comme cela, en lançant explicitement:

 let x = (str as NSSsortingng).subssortingngWithRange(NSMakeRange(0, 3)) 

Notez qu’aucun travail supplémentaire important n’est impliqué ici. “Cast” ne signifie pas “convertir”; la chaîne est effectivement une NSSsortingng. Nous disons simplement à Swift comment regarder cette variable aux fins de cette ligne de code.

La partie vraiment étrange de tout cela est que la méthode Swift, qui cause tous ces problèmes, n’est pas documentée. Je n’ai aucune idée de l’endroit où il est défini; ce n’est pas dans l’en-tête NSSsortingng et ce n’est pas non plus dans l’en-tête Swift.

Dans la nouvelle utilisation de Xcode 7.0

 //: Playground - noun: a place where people can play import UIKit var name = "How do you use Ssortingng.subssortingngWithRange?" let range = name.startIndex.advancedBy(0).. 

entrer la description de l'image ici

La réponse courte est que c’est vraiment difficile à Swift en ce moment. Mon intuition est qu’il ya encore beaucoup de travail à faire sur les méthodes de commodité pour Apple.

Ssortingng.subssortingngWithRange() attend un paramètre Range et, pour autant que je Range , il n’y a pas de méthode générasortingce pour le type Ssortingng.Index . Vous pouvez récupérer les valeurs Ssortingng.Index à partir de aSsortingng.startIndex et aSsortingng.endIndex et appeler .succ() ou .pred() , mais c’est de la folie.

Que diriez-vous d’une extension sur la classe Ssortingng qui prend un bon vieux Int s?

 extension Ssortingng { subscript (r: Range) -> Ssortingng { get { let subStart = advance(self.startIndex, r.startIndex, self.endIndex) let subEnd = advance(subStart, r.endIndex - r.startIndex, self.endIndex) return self.subssortingngWithRange(Range(start: subStart, end: subEnd)) } } func subssortingng(from: Int) -> Ssortingng { let end = countElements(self) return self[from.. Ssortingng { let end = from + length return self[from.. 

Mise à jour: Swift beta 4 résout les problèmes ci-dessous!

En l'état [en version bêta 3 et antérieure], même les chaînes natives de Swift ont quelques problèmes avec la gestion des caractères Unicode. L'icône de chien ci-dessus a fonctionné, mais ce qui suit:

 let harderSsortingng = "1:1️⃣" for character in harderSsortingng { println(character) } 

Sortie:

 1 : 1 ️ ⃣ 

Vous pouvez utiliser ces extensions pour améliorer la subssortingngWithRange

Swift 2.3

 extension Ssortingng { func subssortingngWithRange(start: Int, end: Int) -> Ssortingng { if (start < 0 || start > self.characters.count) { print("start index \(start) out of bounds") return "" } else if end < 0 || end > self.characters.count { print("end index \(end) out of bounds") return "" } let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(end)) return self.subssortingngWithRange(range) } func subssortingngWithRange(start: Int, location: Int) -> Ssortingng { if (start < 0 || start > self.characters.count) { print("start index \(start) out of bounds") return "" } else if location < 0 || start + location > self.characters.count { print("end index \(start + location) out of bounds") return "" } let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(start + location)) return self.subssortingngWithRange(range) } } 

Swift 3

 extension Ssortingng { func subssortingng(start: Int, end: Int) -> Ssortingng { if (start < 0 || start > self.characters.count) { print("start index \(start) out of bounds") return "" } else if end < 0 || end > self.characters.count { print("end index \(end) out of bounds") return "" } let startIndex = self.characters.index(self.startIndex, offsetBy: start) let endIndex = self.characters.index(self.startIndex, offsetBy: end) let range = startIndex.. Ssortingng { if (start < 0 || start > self.characters.count) { print("start index \(start) out of bounds") return "" } else if location < 0 || start + location > self.characters.count { print("end index \(start + location) out of bounds") return "" } let startIndex = self.characters.index(self.startIndex, offsetBy: start) let endIndex = self.characters.index(self.startIndex, offsetBy: start + location) let range = startIndex.. 

Usage:

 let str = "Hello, playground" let subssortingng1 = str.subssortingngWithRange(0, end: 5) //Hello let subssortingng2 = str.subssortingngWithRange(7, location: 10) //playground 

Exemple de code pour savoir comment obtenir une sous-chaîne dans Swift 2.0

(i) Sous-chaîne à partir de l’index de départ

Consortingbution:-

 var str = "Swift is very powerful language!" print(str) str = str.subssortingngToIndex(str.startIndex.advancedBy(5)) print(str) 

Sortie:-

 Swift is very powerful language! Swift 

(ii) Sous-chaîne d’un index particulier

Consortingbution:-

 var str = "Swift is very powerful language!" print(str) str = str.subssortingngFromIndex(str.startIndex.advancedBy(6)).subssortingngToIndex(str.startIndex.advancedBy(2)) print(str) 

Sortie:-

 Swift is very powerful language! is 

J’espère que cela vous aidera!

Solution facile avec peu de code.

Faites une extension qui inclut des sous-chaînes de base que presque toutes les autres langues ont:

 extension Ssortingng { func subSsortingng(start: Int, end: Int) -> Ssortingng { let startIndex = self.index(self.startIndex, offsetBy: start) let endIndex = self.index(startIndex, offsetBy: end) let finalSsortingng = self.subssortingng(from: startIndex) return finalSsortingng.subssortingng(to: endIndex) } } 

Il suffit d’appeler cela avec

 someSsortingng.subSsortingng(start: 0, end: 6) 

Cela fonctionne dans mon terrain de jeu 🙂

 Ssortingng(seq: Array(str)[2...4]) 

Mis à jour pour Xcode 7. Ajoute une extension de chaîne:

Utilisation:

 var chuck: Ssortingng = "Hello Chuck Norris" chuck[6...11] // => Chuck 

La mise en oeuvre:

 extension Ssortingng { /** Subscript to allow for quick Ssortingng subssortingngs ["Hello"][0...1] = "He" */ subscript (r: Range) -> Ssortingng { get { let start = self.startIndex.advancedBy(r.startIndex) let end = self.startIndex.advancedBy(r.endIndex - 1) return self.subssortingngWithRange(start.. 

essayez ceci dans la cour de récréation

 var str:Ssortingng = "Hello, playground" let range = Range(start:advance(str.startIndex,1), end: advance(str.startIndex,8)) 

ça te donnera “ello, p”

Cependant, là où cela devient vraiment intéressant, c’est que si vous faites que le dernier index soit plus grand que la chaîne dans le terrain de jeu, il affichera toutes les chaînes que vous avez définies après str: o

Range () semble être une fonction générique de sorte qu’il doit connaître le type auquel il est confronté.

Vous devez également lui donner la chaîne que vous êtes intéressé par les terrains de jeux car il semble contenir toutes les piqûres les unes après les autres avec leur nom de variable après.

Alors

 var str:Ssortingng = "Hello, playground" var str2:Ssortingng = "I'm the next ssortingng" let range = Range(start:advance(str.startIndex,1), end: advance(str.startIndex,49)) 

donne “ello, playground str Je suis la prochaine ssortingng str2 “

fonctionne même si str2 est défini avec un let

🙂

Rob Napier avait déjà donné une réponse géniale en utilisant l’indice. Mais j’ai ressenti un inconvénient car il n’existe pas de vérification des conditions hors-limites. Cela peut avoir tendance à s’écraser. J’ai donc modifié l’extension et la voici

 extension Ssortingng { subscript (r: Range) -> Ssortingng? { //Optional Ssortingng as return value get { let ssortingngCount = self.characters.count as Int //Check for out of boundary condition if (ssortingngCount < r.endIndex) || (stringCount < r.startIndex){ return nil } let startIndex = self.startIndex.advancedBy(r.startIndex) let endIndex = self.startIndex.advancedBy(r.endIndex - r.startIndex) return self[Range(start: startIndex, end: endIndex)] } } } 

Sortie ci-dessous

 var str2 = "Hello, World" var str3 = str2[0...5] //Hello, var str4 = str2[0..<5] //Hello var str5 = str2[0..<15] //nil 

Donc, je suggère toujours de vérifier si laisser

 if let ssortingng = str[0...5] { //Manipulate your ssortingng safely } 

En swift3

Par exemple: une variable “Duke James Thomas”, nous devons avoir “James”.

 let name = "Duke James Thomas" let range: Range = name.range(of:"James")! let lastrange: Range = img.range(of:"Thomas")! var middlename = name[range.lowerBound.. 

Prenant une page de Rob Napier, j’ai développé ces extensions de chaînes communes , dont deux sont:

 subscript (r: Range) -> Ssortingng { get { let startIndex = advance(self.startIndex, r.startIndex) let endIndex = advance(self.startIndex, r.endIndex - 1) return self[Range(start: startIndex, end: endIndex)] } } func subSsortingng(startIndex: Int, length: Int) -> Ssortingng { var start = advance(self.startIndex, startIndex) var end = advance(self.startIndex, startIndex + length) return self.subssortingngWithRange(Range(start: start, end: end)) } 

Usage:

 "Awesome"[3...7] //"some" "Awesome".subSsortingng(3, length: 4) //"some" 

Voici comment vous obtenez une plage à partir d’une chaîne:

 var str = "Hello, playground" let startIndex = advance(str.startIndex, 1) let endIndex = advance(startIndex, 8) let range = startIndex.. 

Le point clé est que vous passez une plage de valeurs de type Ssortingng.Index (c'est ce que retourne d'avance) au lieu d'entiers.

La raison pour laquelle cela est nécessaire est que les chaînes de Swift n'ont pas d'access aléatoire (à cause de la longueur variable des caractères Unicode). Vous ne pouvez pas non plus faire str[1] . Ssortingng.Index est conçu pour fonctionner avec leur structure interne.

Vous pouvez cependant créer une extension avec un indice qui le fait pour vous, vous pouvez donc simplement passer une série d'entiers (voir par exemple la réponse de Rob Napier ).

J’ai essayé de trouver quelque chose de pythonique.

Tous les indices ici sont excellents, mais les moments où j’ai vraiment besoin de quelque chose de simple, c’est généralement quand je veux compter à partir de l’arrière, par exemple ssortingng.endIndex.advancedBy(-1)

Il prend en charge les valeurs nil , à la fois pour l’index de début et de fin, où nil signifie index à 0 pour start, ssortingng.characters.count pour end.

 extension Ssortingng { var subSsortingng: (Int?) -> (Int?) -> Ssortingng { return { (start) in { (end) in let startIndex = start ?? 0 < 0 ? self.endIndex.advancedBy(start!) : self.startIndex.advancedBy(start ?? 0) let endIndex = end ?? self.characters.count < 0 ? self.endIndex.advancedBy(end!) : self.startIndex.advancedBy(end ?? self.characters.count) return startIndex > endIndex ? "" : self.subssortingngWithRange(startIndex ..< endIndex) } } } } let dog = "Dog‼🐶" print(dog.subString(nil)(-1)) // Dog!! 

MODIFIER

Une solution plus élégante:

 public extension Ssortingng { struct Subssortingng { var start: Int? var ssortingng: Ssortingng public subscript(end: Int?) -> Ssortingng { let startIndex = start ?? 0 < 0 ? string.endIndex.advancedBy(start!) : string.startIndex.advancedBy(start ?? 0) let endIndex = end ?? string.characters.count < 0 ? string.endIndex.advancedBy(end!) : string.startIndex.advancedBy(end ?? string.characters.count) return startIndex > endIndex ? "" : ssortingng.subssortingngWithRange(startIndex ..< endIndex) } } public subscript(start: Int?) -> Subssortingng { return Subssortingng(start: start, ssortingng: self) } } let dog = "Dog‼🐶" print(dog[nil][-1]) // Dog!! 

Commencez par créer la plage, puis la sous-chaîne. Vous pouvez utiliser fromIndex.. syntax comme ça:

 let range = fullSsortingng.startIndex.. 

Voici un exemple pour obtenir un ID de vidéo uniquement .ie (6oL687G0Iso) à partir de l’URL complète dans swift

 let str = "https://www.youtube.com/watch?v=6oL687G0Iso&list=PLKmzL8Ib1gsT-5LN3V2h2H14wyBZTyvVL&index=2" var arrSaprate = str.componentsSeparatedBySsortingng("v=") let start = arrSaprate[1] let rangeOfID = Range(start: start.startIndex,end:start.startIndex.advancedBy(11)) let subssortingng = start[rangeOfID] print(subssortingng) 
 let startIndex = text.startIndex var range = startIndex.advancedBy(1) ..< text.endIndex.advancedBy(-4) let substring = text.substringWithRange(range) 

Échantillon complet, vous pouvez voir ici

http://www.learnswiftonline.com/reference-guides/ssortingng-reference-guide-for-swift/ montre que cela fonctionne bien:

 var str = "abcd" str = str.subssortingngToIndex(1) 

Eh bien, j’ai eu le même problème et résolu avec la fonction “bridgeToObjectiveC ()”:

 var helloworld = "Hello World!" var world = helloworld.bridgeToObjectiveC().subssortingngWithRange(NSMakeRange(6,6)) println("\(world)") // should print World! 

Veuillez noter que dans l’exemple, subssortingngWithRange en conjonction avec NSMakeRange prend la partie de la chaîne commençant à l’index 6 (caractère “W”) et terminant à l’index 6 + 6 positions en avant (caractère “!”)

À votre santé.

Vous pouvez utiliser n’importe quelle méthode de sous-chaîne dans une extension Swift Ssortingng que j’ai écrite https://bit.ly/JSsortingng .

 var ssortingng = "hello" var sub = ssortingng.subssortingngFrom(3) // or ssortingng[3...5] println(sub)// "lo" 

Si vous avez un NSRange , le pontage vers NSSsortingng fonctionne de manière transparente. Par exemple, je travaillais avec UITextFieldDelegate et je voulais rapidement calculer la nouvelle valeur de chaîne lorsqu’elle demandait si elle devait remplacer la plage.

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { let newSsortingng = (textField.text as NSSsortingng).ssortingngByReplacingCharactersInRange(range, withSsortingng: ssortingng) println("Got new ssortingng: ", newSsortingng) } 

Extension simple pour Ssortingng :

 extension Ssortingng { func subssortingngToIndex(index: Int) -> Ssortingng { return self[startIndex...startIndex.advancedBy(min(index, characters.count - 1))] } } 

Si vous ne vous souciez pas de la performance … c’est probablement la solution la plus concise de Swift 4

 extension Ssortingng { subscript(range: CountableClosedRange) -> Ssortingng { return enumerated().filter{$0.offset >= range.first! && $0.offset < range.last!} .reduce(""){$0 + String($1.element)} } } 

Cela vous permet de faire quelque chose comme ceci:

 let myStr = "abcd" myStr[0..<2] // produces "ab"