Je veux supprimer le premier caractère d'une chaîne. Jusqu'ici, la chose la plus succincte que j'ai trouvée est:
display.text = display.text!.substringFromIndex(advance(display.text!.startIndex, 1))
Je sais que nous ne pouvons pas indexer dans une chaîne avec un Int
à cause de Unicode, mais cette solution semble terriblement détaillée. Y a-t-il un autre moyen que je néglige?
Si vous utilisez Swift 3 , vous pouvez ignorer la deuxième section de cette réponse. La bonne nouvelle est que ceci est de nouveau succinct! En utilisant simplement la nouvelle méthode remove (at :) de String.
var myString = "Hello, World"
myString.remove(at: myString.startIndex)
myString // "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é strings characters
et reconvertir ensuite le résultat en chaîne. dropFirst est également devenu une méthode, pas une fonction.
let original = "Hello" // Hello
let sliced = String(original.characters.dropFirst()) // Ello
Une autre alternative consiste à utiliser la fonction suffixe pour épisser le UTF16View
de la chaîne. Bien sûr, cela doit également être reconverti en chaîne.
let original = "Hello" // Hello
let sliced = String(suffix(original.utf16, original.utf16.count - 1)) // Ello
Tout cela pour dire que la solution que j'ai fournie à l'origine s'est avérée ne pas être la manière la plus succincte de le faire dans les nouvelles versions de Swift. Je recommande de recourir à la solution @chris avec removeAtIndex()
si vous recherchez une solution courte et intuitive.
var original = "Hello" // Hello
let removedChar = original.removeAtIndex(original.startIndex)
original // Ello
Et comme l'a souligné @vacawama dans les commentaires ci-dessous, une autre option qui ne modifie pas la chaîne d'origine consiste à utiliser substringFromIndex.
let original = "Hello" // Hello
let substring = original.substringFromIndex(advance(original.startIndex, 1)) // Ello
Ou si vous cherchez à supprimer un caractère du début et de la fin de la chaîne, vous pouvez utiliser substringWithRange. Veillez simplement à vous prémunir contre la situation lorsque startIndex + n > endIndex - m
.
let original = "Hello" // Hello
let newStartIndex = advance(original.startIndex, 1)
let newEndIndex = advance(original.endIndex, -1)
let substring = original.substringWithRange(newStartIndex..<newEndIndex) // ell
La dernière ligne peut également être écrite en utilisant la notation en indice.
let substring = original[newStartIndex..<newEndIndex]
Mise à jour pour Swift 4
Dans Swift 4, String
est à nouveau conforme à 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 Substring
, vous devez donc le transmettre au constructeur String
pour récupérer une String
:
let str = "hello"
let result1 = String(str.dropFirst()) // "Ello"
let result2 = String(str.dropLast()) // "hell"
dropFirst()
et dropLast()
utilisent également une Int
pour spécifier le nombre de caractères à supprimer:
let result3 = String(str.dropLast(3)) // "he"
let result4 = String(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 = String(str.dropFirst(10)) // ""
Mise à jour pour Swift 3
Si vous souhaitez simplement supprimer le premier caractère et modifier la chaîne d'origine, reportez-vous à la réponse de @ MickMacCallum. Si vous souhaitez créer une nouvelle chaîne dans le processus, utilisez substring(from:)
. Avec une extension à String
, vous pouvez masquer la laideur de substring(from:)
et substring(to:)
afin de créer des ajouts utiles pour ajuster le début et la fin d'une String
:
extension String {
func chopPrefix(_ count: Int = 1) -> String {
return substring(from: index(startIndex, offsetBy: count))
}
func chopSuffix(_ count: Int = 1) -> String {
return substring(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 bloqueront si le nombre de lettres disponibles dans la chaîne est insuffisant. Il incombe à l'appelant de les utiliser correctement. Ceci est une décision de conception valide. On pourrait leur écrire pour renvoyer un optionnel qui devra alors être déballé 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 à String
, vous pouvez masquer la laideur de substringFromIndex
et substringToIndex
:
extension String {
func chopPrefix(count: Int = 1) -> String {
return self.substringFromIndex(advance(self.startIndex, count))
}
func chopSuffix(count: Int = 1) -> String {
return self.substringToIndex(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 bloqueront si le nombre de lettres disponibles dans la chaîne est insuffisant. Il incombe à l'appelant de les utiliser correctement. Ceci est une décision de conception valide. On pourrait leur écrire pour renvoyer un optionnel qui devra alors être déballé par l'appelant.
Dans Swift 1.2 , vous devrez appeler chopPrefix
comme ceci:
"hello".chopPrefix(count: 3) // "lo"
ou vous pouvez ajouter un trait de soulignement _
aux définitions de fonction pour supprimer le nom du paramètre:
extension String {
func chopPrefix(_ count: Int = 1) -> String {
return self.substringFromIndex(advance(self.startIndex, count))
}
func chopSuffix(_ count: Int = 1) -> String {
return self.substringToIndex(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) -> String {
return self.substringFromIndex(self.startIndex.advancedBy(count))
}
func chopSuffix(count: Int = 1) -> String {
return self.substringFromIndex(self.endIndex.advancedBy(count))
}
Swift 3.0
func chopPrefix(_ count: Int = 1) -> String {
return self.substring(from: self.characters.index(self.startIndex, offsetBy: count))
}
func chopSuffix(_ count: Int = 1) -> String {
return self.substring(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 String or Substring directly") public var characters: String.CharacterView
func chopPrefix(_ count: Int = 1) -> String {
if count >= 0 && count <= self.count {
return self.substring(from: String.Index(encodedOffset: count))
}
return ""
}
func chopSuffix(_ count: Int = 1) -> String {
if count >= 0 && count <= self.count {
return self.substring(to: String.Index(encodedOffset: self.count - count))
}
return ""
}
Swift 4
extension String {
func chopPrefix(_ count: Int = 1) -> String {
if count >= 0 && count <= self.count {
let indexStartOfText = self.index(self.startIndex, offsetBy: count)
return String(self[indexStartOfText...])
}
return ""
}
func chopSuffix(_ count: Int = 1) -> String {
if count >= 0 && count <= self.count {
let indexEndOfText = self.index(self.endIndex, offsetBy: -count)
return String(self[..<indexEndOfText])
}
return ""
}
}
Dans Swift 2, procédez comme suit:
let cleanedString = String(theString.characters.dropFirst())
Je recommande https://www.mikeash.com/pyblog/friday-qa-2015-11-06-why-is-swifts-string-api-so-hard.html pour bien comprendre Swins .
Et ça?
s.removeAtIndex(s.startIndex)
Bien entendu, cela suppose que votre chaîne est mutable. Il retourne le caractère qui a été supprimé, mais modifie la chaîne d'origine.
Cela dépend de ce que vous voulez que le résultat final soit (mutant ou non mutant).
À partir de Swift 4.1:
En mutation:
var str = "hello"
str.removeFirst() // changes str
Non mutable:
let str = "hello"
let strSlice = str.dropFirst() // makes a slice without the first letter
let str2 = String(strSlice)
Remarques:
nonmutating
. Subjectivement, la combinaison des deux dernières étapes serait plus succincte. dropFirst
me semble un peu étrange, car si je comprends les Directives de conception de l'API Swift correctement, dropFirst
devrait en réalité ressembler à dropingFirst
car elle ne modifie pas. Juste une pensée :). Les réponses précédentes sont plutôt bonnes, mais à partir d’aujourd’hui, je pense que c’est peut-être le moyen le plus succinct d’enlever le premier caractère d’une chaîne dans Swift 4 :
var line: String = "This is a string..."
var char: Character? = nil
char = line.removeFirst()
print("char = \(char)") // char = T
print("line = \(line)") // line = his is a string ...
Je ne connais rien de plus succinct, mais vous pouvez facilement implémenter le préfixe ++
, par exemple,
public prefix func ++ <I: ForwardIndexType>(index: I) -> I {
return advance(index, 1)
}
Après quoi, vous pouvez l’utiliser de manière très succincte:
str.substringFromIndex(++str.startIndex)
"en_US, fr_CA, es_US" .chopSuffix (5) .chopPrefix (5) // ", fr_CA,"
extension String {
func chopPrefix(count: Int = 1) -> String {
return self.substringFromIndex(self.startIndex.advancedBy(count))
}
func chopSuffix(count: Int = 1) -> String {
return self.substringToIndex(self.endIndex.advancedBy(-count))
}
}
Dans Swift 2, utilisez cette extension String:
extension String
{
func substringFromIndex(index: Int) -> String
{
if (index < 0 || index > self.characters.count)
{
print("index \(index) out of bounds")
return ""
}
return self.substringFromIndex(self.startIndex.advancedBy(index))
}
}
display.text = display.text!.substringFromIndex(1)
extension String {
func chopPrefix(_ count: UInt = 1) -> String {
return substring(from: characters.index(startIndex, offsetBy: Int(count)))
}
func chopSuffix(_ count: UInt = 1) -> String {
return substring(to: characters.index(endIndex, offsetBy: -Int(count)))
}
}
class StringChopTests: 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")
}
}
Voici une version Swift4 crash de la version chopPrefix
, en laissant chopSuffix
à la communauté ...
extension String {
func chopPrefix(_ count: Int = 1) -> String {
return count>self.count ? self : String(self[index(self.startIndex, offsetBy: count)...])
}
}
Pour supprimer le premier caractère de la chaîne
let choppedString = String(txtField.text!.characters.dropFirst())