Comment obtenir le nième caractère d'une chaîne? J'ai essayé l' []
accessoire bracket ( ) sans succès.
var string = "Hello, world!"
var firstChar = string[0] // Throws error
ERREUR: 'indice' n'est pas disponible: ne peut pas inscrire une chaîne avec un Int, voir le commentaire de la documentation pour discussion
swift
string
collections
character
Mohsen
la source
la source
var firstChar = string.index(string.startIndex, offsetBy: 0)
placestring.startIndex
? Pour le premier caractèrestring[string.startIndex]
ou simplementstring.first
. Notez que la première approche dont vous auriez besoin pour vérifier si la chaîne est vide en premier la deuxième renvoie une optionRéponses:
Attention: Veuillez consulter la réponse de Leo Dabus pour une implémentation correcte de Swift 4 et Swift 5.
Swift 4 ou version ultérieure
Le
Substring
type a été introduit dans Swift 4 pour rendre les sous-chaînes plus rapides et plus efficaces en partageant le stockage avec la chaîne d'origine, c'est donc ce que les fonctions d'indice devraient renvoyer.Essayez-le ici
Pour convertir le
Substring
en unString
, vous pouvez simplement le faireString(string[0..2])
, mais vous ne devriez le faire que si vous prévoyez de conserver la sous-chaîne. Sinon, il est plus efficace de le garder aSubstring
.Ce serait formidable si quelqu'un pouvait trouver un bon moyen de fusionner ces deux extensions en une seule. J'ai essayé d'étendreRemarque: Cette réponse a déjà été modifiée, elle est correctement implémentée et fonctionne désormais également pour les sous-chaînes. Assurez-vous simplement d'utiliser une plage valide pour éviter de planter lorsque vous indiquez votre type StringProtocol. Pour un indice avec une plage qui ne se bloquera pas avec des valeurs hors plage, vous pouvez utiliser cette implémentationStringProtocol
sans succès, car laindex
méthode n'existe pas là-bas.Pourquoi n'est-ce pas intégré?
Le message d'erreur indique "voir le commentaire de la documentation pour la discussion" . Apple fournit l'explication suivante dans le fichier UnavailableStringAPIs.swift :
la source
Cannot find an overload for 'advance' that accepts an argument list of type '(String.Index, T)'
...String.Index
etInt
ne sont pas compatibles.Cannot subscript a value of type 'String'...
vérifiez cette réponse: stackoverflow.com/a/31265316/649379Ambiguous use of 'subscript'
.fatal error: Can't form a Character from an empty String
Swift 5.2
Vous devrez ajouter cette extension String à votre projet (elle est entièrement testée):
Même si Swift avait toujours une solution prête à l'emploi à ce problème (sans l'extension String, que j'ai fournie ci-dessous), je recommanderais toujours fortement d' utiliser l'extension. Pourquoi? Parce que cela m'a fait gagner des dizaines d'heures de migration pénible à partir des premières versions de Swift, où la syntaxe de String changeait presque à chaque version, mais tout ce que j'avais à faire était de mettre à jour l'implémentation de l'extension plutôt que de refactoriser l'ensemble du projet. Fais ton choix.
la source
range.upperBound - range.lowerBound
pourrange.count
extension 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]) } } }
Je viens de trouver cette solution de contournement soignée
la source
var firstChar = Array(string!)[0]
Sinon, cela diraadd arrayLiteral
Pas d'indexation en utilisant des entiers, uniquement en utilisant
String.Index
. Surtout avec une complexité linéaire. Vous pouvez également créer des plages à partir de cesString.Index
sous-chaînes et les utiliser.Swift 3.0
Swift 2.x
Notez que vous ne pouvez jamais utiliser un index (ou une plage) créé à partir d'une chaîne vers une autre chaîne
la source
String
les index sont uniques à une chaîne. Cela est dû au fait que différentes chaînes peuvent avoir différents UTF-16 multi-unitésCharacters
et / ou à différentes positions, de sorte que les index des unités UTF-16 ne correspondent pas, peuvent tomber au-delà de la fin ou du point à l'intérieur d'un UTF-16 multi-unitésCharacter
...
est maintenant..<
(dans votre affectation àrange
)var lastChar = string[string.endIndex.predecessor()]
Xcode 11 • Swift 5.1
Vous pouvez étendre StringProtocol pour rendre l'index disponible également aux sous-chaînes:
Essai
la source
return String(Array(characters)[range])
à Swift 3?Swift 4
Chaîne à l'index
Sous-chaîne
Premiers n caractères
N derniers caractères
Swift 2 et 3
** Chaîne à l'index **
Swift 2
Swift 3
Sous-chaîne deIndex àIndex
Swift 2
Swift 3
Premiers n caractères
N derniers caractères
la source
Swift 2.0 à partir de Xcode 7 GM Seed
Pour le nième caractère, remplacez 0 par n-1.
Édition: Swift 3.0
nb il existe des moyens plus simples de saisir certains caractères dans la chaîne
par exemple
let firstChar = text.characters.first
la source
Si vous voyez
Cannot subscript a value of type 'String'...
utiliser cette extension:Swift 3
Swift 2.3
Source: http://oleb.net/blog/2014/07/swift-strings/
la source
Solution Swift 2.2:
L'extension suivante fonctionne dans Xcode 7, c'est une combinaison de cette solution et de la conversion de la syntaxe Swift 2.0.
la source
La classe de chaîne rapide ne permet pas d'obtenir un caractère à un index spécifique en raison de sa prise en charge native des caractères UTF. La longueur variable d'un caractère UTF en mémoire rend impossible le passage direct à un caractère. Cela signifie que vous devez boucler manuellement la chaîne à chaque fois.
Vous pouvez étendre String pour fournir une méthode qui parcourra les caractères jusqu'à ce que votre index souhaité
la source
myString.bridgeToObjectiveC().characterAtIndex(0)
ou(string as NSString ).characterAtIndex(0)
retourne une valeur Int du caractèreNSString
méthodes pour accéder à des caractères individuels d'un natif SwiftString
- les deux mécanismes utilisent différents de comptage, de sorte que vous obtiendrez des résultats imprévisibles avec des caractères Unicode plus élevés. La première méthode doit être sûre (une fois les bogues Unicode de Swift traités).En passant, il existe quelques fonctions applicables directement à la représentation de chaîne de caractères d'une chaîne, comme ceci:
Le résultat est de type Caractère, mais vous pouvez le convertir en Chaîne.
Ou ca:
:-)
la source
Swift 4
C'est probablement la meilleure façon de résoudre ce problème une seule fois. Vous souhaiterez probablement convertir la chaîne sous forme de tableau en premier, puis convertir à nouveau le résultat en chaîne. Sinon, un caractère sera retourné au lieu d'une chaîne.
L'exemple
String(Array("HelloThere")[1])
retournera "e" sous forme de chaîne.(Array("HelloThere")[1]
renverra "e" en tant que personnage.Swift ne permet pas d'indexer les chaînes comme des tableaux, mais cela fait le travail, à la manière d'une force brute.
la source
Ma solution très simple:
Swift 4.1:
Swift 5.1:
la source
let flags = "🇺🇸🇧🇷"
flags[String.Index(utf16Offset: 4, in: flags)] // "🇧🇷"
Vous pouvez le faire en convertissant String en tableau et l'obtenir par index spécifique en utilisant l'indice comme ci-dessous
la source
Je viens d'avoir le même problème. Faites simplement ceci:
la source
NSString
.Swift3
Vous pouvez utiliser la syntaxe en indice pour accéder au caractère à un index de chaîne particulier.
Visitez https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html
ou nous pouvons faire une extension de chaîne dans Swift 4
USAGE:
la source
Ma solution est sur une seule ligne, en supposant que cadena est la chaîne et 4 est la nième position que vous souhaitez:
Simple ... Je suppose que Swift inclura plus de choses sur les sous-chaînes dans les futures versions.
la source
var charAtIndex = string[advance(string.startIndex, 10)]
dans la réponse de Sulthan?Swift 3: une autre solution (testée en aire de jeux)
Usage:
la source
Mise à jour pour la sous-chaîne swift 2.0
la source
Je pense qu'une réponse rapide pour obtenir le premier caractère pourrait être:
C'est tellement élégant et performant que:
Mais .. si vous voulez manipuler et faire plus d'opérations avec des chaînes, vous pourriez penser créer une extension .. il y a une extension avec cette approche, elle est assez similaire à celle déjà publiée ici:
}
MAIS C'EST UNE IDÉE TERRIBLE !!
L'extension ci-dessous est horriblement inefficace. Chaque fois qu'une chaîne est accédée avec un entier, une fonction O (n) pour avancer son index de départ est exécutée. L'exécution d'une boucle linéaire à l'intérieur d'une autre boucle linéaire signifie que cette boucle est accidentellement O (n2) - à mesure que la longueur de la chaîne augmente, le temps que prend cette boucle augmente de façon quadratique.
Au lieu de cela, vous pouvez utiliser la collection de chaînes de caractères.
la source
Swift 3
Usage
Trucs et astuces de programmation utiles (écrits par moi)
la source
Obtenir et définir un indice (chaîne et sous-chaîne) - Swift 4.2
Swift 4.2, Xcode 10
J'ai basé ma réponse sur la réponse de @alecarlson . La seule grande différence est que vous pouvez obtenir un
Substring
ou unString
retour (et dans certains cas, un seulCharacter
). Vous pouvez égalementget
etset
l'indice. Enfin, la mienne est un peu plus lourde et plus longue que la réponse de @alecarlson et en tant que telle, je vous suggère de la mettre dans un fichier source.Extension:
la source
Swift 4.2
Cette réponse est idéale car elle s'étend
String
et tous sesSubsequences
(Substring
) en une seule extensionUsage
la source
start
etend
) destartIndex
. Vous pouvez simplement compenser l'end
index à l'aide de range.count et compenser l'start
indexÀ l'heure actuelle, l'indice (_ :) n'est pas disponible. Et on ne peut pas faire ça
avec string.We doit fournir "String.Index" Mais, comment pouvons-nous donner notre propre numéro d'index de cette façon, au lieu de cela, nous pouvons utiliser,
la source
string[string.startIndex]
? BTW, le code ne se comporterait pas correctement / ne se compilerait pas, car vous avez utilisé deux noms de variables différents.Swift 4.2 ou version ultérieure
Gamme et indice de gamme partielle en utilisant
String
laindices
propriété deComme variation de la réponse agréable de @LeoDabus , nous pouvons ajouter une extension supplémentaire à
DefaultIndices
dans le but de nous permettre de nous rabattre sur laindices
propriété deString
lors de la mise en œuvre des indices personnalisés (parInt
plages spécialisées et plages partielles) pour ces derniers.Merci @LeoDabus de m'avoir pointé vers l'utilisation de la
indices
propriété comme (autre) alternative à laString
souscription!la source
swiftenv
quand je le fais, cependant, je suppose qu'il sera également mis à jour avec la version 4.2 bientôt.Swift 5.1.3:
Ajoutez une extension de chaîne:
la source
Le
String
type de Swift ne fournit pas decharacterAtIndex
méthode car il existe plusieurs façons de coder une chaîne Unicode. Allez-vous avec UTF8, UTF16 ou autre chose?Vous pouvez accéder aux
CodeUnit
collections en récupérant les propriétésString.utf8
etString.utf16
. Vous pouvez également accéder à laUnicodeScalar
collection en récupérant laString.unicodeScalars
propriété.Dans l'esprit de
NSString
l'implémentation de, je retourne ununichar
type.la source
Afin de nourrir le sujet et de montrer des possibilités d'indices rapides, voici une petite chaîne basée sur des indices "substring-toolbox"
Ces méthodes sont sûres et ne dépassent jamais les index de chaîne
la source
Une solution de type python, qui vous permet d'utiliser un index négatif,
pourrait être:
Soit dit en passant, cela peut valoir la peine de transposer toute la notation de tranche de python
la source
Vous pouvez également convertir une chaîne en tableau de caractères comme ça:
C'est le moyen d'obtenir char à l'index spécifié en temps constant.
L'exemple ci-dessous ne fonctionne pas en temps constant, mais nécessite un temps linéaire. Donc, si vous avez beaucoup de recherche dans String par index, utilisez la méthode ci-dessus.
la source