Quelle est la manière la plus succincte de supprimer le premier caractère d’une chaîne dans Swift?

Je veux supprimer le premier caractère d’une chaîne. Jusqu’à présent, la chose la plus succincte que j’ai imaginée est la suivante:

display.text = display.text!.subssortingngFromIndex(advance(display.text!.startIndex, 1)) 

Je sais que nous ne pouvons pas indexer une chaîne avec un Int cause d’Unicode, mais cette solution semble terriblement verbeuse. Y a-t-il une autre façon que je néglige?

Si vous utilisez Swift 3 , vous pouvez ignorer la deuxième partie de cette réponse. La bonne nouvelle est que cela est à nouveau concis! Juste en utilisant la nouvelle méthode de suppression (at 🙂 de Ssortingng.

 var mySsortingng = "Hello, World" mySsortingng.remove(at: mySsortingng.startIndex) mySsortingng // "ello, World" 

J’aime la fonction globale dropFirst() pour cela.

 let original = "Hello" // Hello let sliced = dropFirst(original) // ello 

C’est court, clair et fonctionne pour tout ce qui est conforme au protocole Sliceable.

Si vous utilisez Swift 2 , cette réponse a changé. Vous pouvez toujours utiliser dropFirst, mais pas sans supprimer le premier caractère de votre propriété de characters chaînes, puis convertir le résultat en chaîne. dropFirst est également devenu une méthode et non une fonction.

 let original = "Hello" // Hello let sliced = Ssortingng(original.characters.dropFirst()) // ello 

Une autre alternative consiste à utiliser la fonction suffixe pour épisser le UTF16View la chaîne. Bien sûr, cela doit également être reconverti en chaîne.

 let original = "Hello" // Hello let sliced = Ssortingng(suffix(original.utf16, original.utf16.count - 1)) // ello 

Tout cela pour dire que la solution que j’ai initialement proposée ne s’est pas révélée être la manière la plus succincte de le faire dans les nouvelles versions de Swift. Je recommande de revenir sur la solution de removeAtIndex() utilisant removeAtIndex() si vous recherchez une solution courte et intuitive.

 var original = "Hello" // Hello let removedChar = original.removeAtIndex(original.startIndex) original // ello 

Et comme le fait remarquer @vacawama dans les commentaires ci-dessous, une autre option qui ne modifie pas la chaîne d’origine consiste à utiliser subssortingngFromIndex.

 let original = "Hello" // Hello let subssortingng = original.subssortingngFromIndex(advance(original.startIndex, 1)) // ello 

Ou si vous cherchez à supprimer un caractère au début et à la fin de la chaîne, vous pouvez utiliser subssortingngWithRange. Veillez simplement à vous prémunir contre la condition lorsque startIndex + n > endIndex - m .

 let original = "Hello" // Hello let newStartIndex = advance(original.startIndex, 1) let newEndIndex = advance(original.endIndex, -1) let subssortingng = original.subssortingngWithRange(newStartIndex.. 

La dernière ligne peut également être écrite en utilisant une notation en indice.

 let subssortingng = original[newStartIndex.. 

Mise à jour pour Swift 4

Dans Swift 4, Ssortingng conforme à nouveau à Collection , il est donc possible d’utiliser dropFirst et dropLast pour couper les débuts et les fins des chaînes. Le résultat est de type Subssortingng , vous devez donc le transmettre au constructeur Ssortingng pour récupérer une Ssortingng :

 let str = "hello" let result1 = Ssortingng(str.dropFirst()) // "ello" let result2 = Ssortingng(str.dropLast()) // "hell" 

dropFirst() et dropLast() prennent également un Int pour spécifier le nombre de caractères à supprimer:

 let result3 = Ssortingng(str.dropLast(3)) // "he" let result4 = Ssortingng(str.dropFirst(4)) // "o" 

Si vous spécifiez plus de caractères à supprimer que dans la chaîne, le résultat sera la chaîne vide ( "" ).

 let result5 = Ssortingng(str.dropFirst(10)) // "" 

Mise à jour pour Swift 3

Si vous voulez juste supprimer le premier caractère et que vous voulez changer la chaîne d’origine, consultez la réponse de @ MickMacCallum. Si vous souhaitez créer une nouvelle chaîne dans le processus, utilisez la subssortingng(from:) . Avec une extension à Ssortingng , vous pouvez masquer la laideur de la subssortingng(from:)subssortingng(from:) et de la subssortingng(to:)subssortingng(to:) pour créer des ajouts utiles pour découper le début et la fin d’une Ssortingng :

 extension Ssortingng { func chopPrefix(_ count: Int = 1) -> Ssortingng { return subssortingng(from: index(startIndex, offsetBy: count)) } func chopSuffix(_ count: Int = 1) -> Ssortingng { return subssortingng(to: index(endIndex, offsetBy: -count)) } } "hello".chopPrefix() // "ello" "hello".chopPrefix(3) // "lo" "hello".chopSuffix() // "hell" "hello".chopSuffix(3) // "he" 

Comme dropFirst et dropLast avant eux, ces fonctions se dropLast s’il n’y a pas assez de lettres disponibles dans la chaîne. Il incombe à l’appelant de les utiliser correctement. Ceci est une décision de conception valide. On pourrait les écrire pour renvoyer une option qui devrait alors être déballée par l’appelant.


Swift 2.x

Hélas, dans Swift 2 , dropFirst et dropLast (la meilleure solution précédente) ne sont plus aussi pratiques qu’avant. Avec une extension à Ssortingng , vous pouvez masquer la laideur de subssortingngFromIndex et subssortingngToIndex :

 extension Ssortingng { func chopPrefix(count: Int = 1) -> Ssortingng { return self.subssortingngFromIndex(advance(self.startIndex, count)) } func chopSuffix(count: Int = 1) -> Ssortingng { return self.subssortingngToIndex(advance(self.endIndex, -count)) } } "hello".chopPrefix() // "ello" "hello".chopPrefix(3) // "lo" "hello".chopSuffix() // "hell" "hello".chopSuffix(3) // "he" 

Comme dropFirst et dropLast avant eux, ces fonctions se dropLast s’il n’y a pas assez de lettres disponibles dans la chaîne. Il incombe à l’appelant de les utiliser correctement. Ceci est une décision de conception valide. On pourrait les écrire pour renvoyer une option qui devrait alors être déballée par l’appelant.


Dans Swift 1.2 , vous devrez appeler chopPrefix comme ceci:

 "hello".chopPrefix(count: 3) // "lo" 

ou vous pouvez append un trait de soulignement _ aux définitions de fonction pour supprimer le nom du paramètre:

 extension Ssortingng { func chopPrefix(_ count: Int = 1) -> Ssortingng { return self.subssortingngFromIndex(advance(self.startIndex, count)) } func chopSuffix(_ count: Int = 1) -> Ssortingng { return self.subssortingngToIndex(advance(self.endIndex, -count)) } } 

Swift 2.2

‘advance’ n’est pas disponible: appelez la méthode ‘advancedBy (n)’ sur l’index

  func chopPrefix(count: Int = 1) -> Ssortingng { return self.subssortingngFromIndex(self.startIndex.advancedBy(count)) } func chopSuffix(count: Int = 1) -> Ssortingng { return self.subssortingngFromIndex(self.endIndex.advancedBy(count)) } 

Swift 3.0

  func chopPrefix(_ count: Int = 1) -> Ssortingng { return self.subssortingng(from: self.characters.index(self.startIndex, offsetBy: count)) } func chopSuffix(_ count: Int = 1) -> Ssortingng { return self.subssortingng(to: self.characters.index(self.endIndex, offsetBy: -count)) } 

Swift 3.2

Une vue du contenu de la chaîne en tant que collection de caractères.

 @available(swift, deprecated: 3.2, message: "Please use Ssortingng or Subssortingng directly") public var characters: Ssortingng.CharacterView 
 func chopPrefix(_ count: Int = 1) -> Ssortingng { if count >= 0 && count < = self.count { return self.substring(from: String.Index(encodedOffset: count)) } return "" } func chopSuffix(_ count: Int = 1) -> Ssortingng { if count >= 0 && count < = self.count { return self.substring(to: String.Index(encodedOffset: self.count - count)) } return "" } 

Rapide 4

 extension Ssortingng { func chopPrefix(_ count: Int = 1) -> Ssortingng { if count >= 0 && count < = self.count { let indexStartOfText = self.index(self.startIndex, offsetBy: count) return String(self[indexStartOfText...]) } return "" } func chopSuffix(_ count: Int = 1) -> Ssortingng { if count >= 0 && count < = self.count { let indexEndOfText = self.index(self.endIndex, offsetBy: -count) return String(self[.. 

Dans Swift 2, faites ceci:

 let cleanedSsortingng = Ssortingng(theSsortingng.characters.dropFirst()) 

Je recommande https://www.mikeash.com/pyblog/friday-qa-2015-11-06-why-is-swifts-ssortingng-api-so-hard.html pour comprendre les chaînes Swift.

Et ça?

 s.removeAtIndex(s.startIndex) 

Cela suppose bien sûr que votre chaîne soit mutable. Il renvoie le caractère qui a été supprimé, mais modifie la chaîne d’origine.

Dépend de ce que vous voulez que le résultat final soit (mutant vs non mutant).

À partir de Swift 4.1:

Mutant:

 var str = "hello" str.removeFirst() // changes str 

Non mutant:

 let str = "hello" let strSlice = str.dropFirst() // makes a slice without the first letter let str2 = Ssortingng(strSlice) 

Remarques:

  • Je mets une étape supplémentaire dans l’exemple non- nonmutating pour plus de clarté. Subjectivement, la combinaison des deux dernières étapes serait plus succincte.
  • La dénomination de dropFirst semble un peu étrange, car si je comprends bien les directives de conception de l’API Swift , dropFirst devrait vraiment être quelque chose comme dropingFirst car il n’est pas mutant. Juste une pensée :).

Je ne connais rien de plus succinct, mais vous pouvez facilement implémenter prefix ++ , par exemple,

 public prefix func ++ (index: I) -> I { return advance(index, 1) } 

Après quoi, vous pouvez l’utiliser très succinctement:

 str.subssortingngFromIndex(++str.startIndex) 

Dans Swift 2, utilisez cette extension de chaîne:

 extension Ssortingng { func subssortingngFromIndex(index: Int) -> Ssortingng { if (index < 0 || index > self.characters.count) { print("index \(index) out of bounds") return "" } return self.subssortingngFromIndex(self.startIndex.advancedBy(index)) } } display.text = display.text!.subssortingngFromIndex(1) 

“en_US, fr_CA, es_US” .chopSuffix (5) .chopPrefix (5) // “, fr_CA,”

 extension Ssortingng { func chopPrefix(count: Int = 1) -> Ssortingng { return self.subssortingngFromIndex(self.startIndex.advancedBy(count)) } func chopSuffix(count: Int = 1) -> Ssortingng { return self.subssortingngToIndex(self.endIndex.advancedBy(-count)) } } 

Les réponses précédentes sont plutôt bonnes, mais à ce jour, je pense que cela pourrait être le moyen le plus succinct de supprimer le premier caractère d’une chaîne dans Swift 4 :

 var line: Ssortingng = "This is a ssortingng..." var char: Character? = nil char = line.removeFirst() print("char = \(char)") // char = T print("line = \(line)") // line = his is a ssortingng ... 

Swift3

 extension Ssortingng { func chopPrefix(_ count: Int = 1) -> Ssortingng { return subssortingng(from: characters.index(startIndex, offsetBy: count)) } func chopSuffix(_ count: Int = 1) -> Ssortingng { return subssortingng(to: characters.index(endIndex, offsetBy: -count)) } } class SsortingngChopTests: XCTestCase { func testPrefix() { XCTAssertEqual("original".chopPrefix(0), "original") XCTAssertEqual("Xfile".chopPrefix(), "file") XCTAssertEqual("filename.jpg".chopPrefix(4), "name.jpg") } func testSuffix() { XCTAssertEqual("original".chopSuffix(0), "original") XCTAssertEqual("fileX".chopSuffix(), "file") XCTAssertEqual("filename.jpg".chopSuffix(4), "filename") } } 

Pour supprimer le premier caractère de la chaîne

 let choppedSsortingng = Ssortingng(txtField.text!.characters.dropFirst()) 

Voici une version de sauvegarde chopPrefix extension chopPrefix , laissant chopSuffix à la communauté …

 extension Ssortingng { func chopPrefix(_ count: Int = 1) -> Ssortingng { return count>self.count ? self : Ssortingng(self[index(self.startIndex, offsetBy: count)...]) } }