Il est temps d'admettre la défaite ...
Dans Objective-C, je pourrais utiliser quelque chose comme:
NSString* str = @"abcdefghi";
[str rangeOfString:@"c"].location; // 2
Dans Swift, je vois quelque chose de similaire:
var str = "abcdefghi"
str.rangeOfString("c").startIndex
... mais cela me donne juste un String.Index
, que je peux utiliser pour réinscrire dans la chaîne d'origine, mais pas extraire un emplacement de.
FWIW, qui String.Index
a un ivar privé appelé _position
qui a la bonne valeur. Je ne vois tout simplement pas comment cela est exposé.
Je sais que je pourrais facilement ajouter ceci à String moi-même. Je suis plus curieux de savoir ce qui me manque dans cette nouvelle API.
Réponses:
Vous n'êtes pas le seul à ne pas trouver la solution.
String
ne met pas en œuvreRandomAccessIndexType
. Probablement parce qu'ils permettent des caractères avec des longueurs d'octets différentes. C'est pourquoi nous devons utiliserstring.characters.count
(count
oucountElements
dans Swift 1.x) pour obtenir le nombre de caractères. Cela s'applique également aux postes. Il_position
s'agit probablement d'un index dans le tableau brut d'octets et ils ne veulent pas l'exposer. LeString.Index
est destiné à nous protéger de l'accès aux octets au milieu des caractères.Cela signifie que tout index que vous obtenez doit être créé à partir de
String.startIndex
ouString.endIndex
(String.Index
implémenteBidirectionalIndexType
). Tout autre indice peut être créé à l'aide des méthodessuccessor
oupredecessor
.Maintenant, pour nous aider avec les indices, il existe un ensemble de méthodes (fonctions dans Swift 1.x):
Swift 4.x
Swift 3.0
Swift 2.x
Swift 1.x
Travailler avec
String.Index
est lourd mais utiliser un wrapper pour indexer par des entiers (voir https://stackoverflow.com/a/25152652/669586 ) est dangereux car il cache l'inefficacité d'une véritable indexation.Notez que l'implémentation de l'indexation Swift a le problème que les index / plages créés pour une chaîne ne peuvent pas être utilisés de manière fiable pour une chaîne différente , par exemple:
Swift 2.x
Swift 1.x
la source
range
envar range = text.rangeOfString("b")
Collection
a untypealias IndexType
. Pour les tableaux, il est défini commeInt
, carString
il est défini commeString.Index
. Les tableaux et les chaînes peuvent également utiliser des plages (pour créer des sous-réseaux et des sous-chaînes). La gamme est un type spécialRange<T>
. Pour les chaînes, c'estRange<String.Index>
pour les tableauxRange<Int>
.Swift 2.0
,distance(text.startIndex, range.startIndex)
devienttext.startIndex.distanceTo(range.startIndex)
String
, exactement commeNSString
dans Foundation, a une méthode appeléehasPrefix(_:)
.Swift 3.0 rend cela un peu plus détaillé:
Extension:
Dans Swift 2.0, cela est devenu plus facile:
Extension:
Implémentation de Swift 1.x:
Pour une solution Swift pure, on peut utiliser:
En extension à
String
:la source
la source
J'ai trouvé cette solution pour swift2:
la source
Swift 5.0
Swift 4.0
la source
Je ne sais pas comment extraire la position de String.Index, mais si vous êtes prêt à vous rabattre sur certains cadres Objective-C, vous pouvez passer à objective-c et le faire de la même manière que vous le faisiez auparavant.
Il semble que certaines méthodes NSString n'aient pas encore été (ou ne seront peut-être pas) portées sur String. Contient aussi vient à l'esprit.
la source
bridgeToObjectiveC()
appel n'est pas nécessaire. Mon problème semble se manifester uniquement lors de l'appelrangeOfString
à une chaîne Swift existante. Cela ressemble à un problème d'API ...Voici une extension de chaîne propre qui répond à la question:
Swift 3:
Swift 2.2:
la source
Vous pouvez également trouver des index d'un caractère dans une seule chaîne comme celle-ci,
Ce qui donne le résultat dans [String.Distance] ie. [Int], comme
la source
Si vous souhaitez utiliser NSString familier, vous pouvez le déclarer explicitement:
Je ne sais pas encore comment faire cela dans Swift.
la source
Si vous voulez connaître la position d'un caractère dans une chaîne en tant que valeur int , utilisez ceci:
la source
value of type 'Range<String.Index>?' has no member 'location'
.Je sais que cela est ancien et qu'une réponse a été acceptée, mais vous pouvez trouver l'index de la chaîne dans quelques lignes de code en utilisant:
Quelques autres bonnes informations sur les cordes Swift ici Strings in Swift
la source
find
n'est pas disponible dans Swift 3Cela a fonctionné pour moi,
cela a fonctionné aussi,
la source
var str = "abcdef"; str.rangeOfString("c").location
soulève une erreur à propos de String.Index n'ayant pas de membre nommé location ...La chaîne de type variable dans Swift contient des fonctions différentes par rapport à NSString dans Objective-C. Et comme Sulthan l'a mentionné,
Ce que vous pouvez faire est de convertir votre variable de type String en NSString (ceci est valide dans Swift). Cela vous donnera accès aux fonctions de NSString.
la source
Si vous y réfléchissez, vous n'avez en fait pas vraiment besoin de la version Int exacte de l'emplacement. La plage ou même le String.Index est suffisant pour extraire à nouveau la sous-chaîne si nécessaire:
la source
La manière la plus simple est:
Dans Swift 3 :
la source
La chaîne est un type de pont pour NSString, alors ajoutez
à votre fichier rapide et utilisez toutes les "anciennes" méthodes.
la source
En termes de réflexion, cela pourrait être appelé une INVERSION. Vous découvrez que le monde est rond au lieu d'être plat. "Vous n'avez pas vraiment besoin de connaître l'INDEX du personnage pour faire des choses avec." Et en tant que programmeur C, j'ai trouvé cela difficile à prendre aussi! Votre ligne "let index = letters.characters.indexOf (" c ")!" est suffisant en soi. Par exemple, pour supprimer le c que vous pourriez utiliser ... (coller le terrain de jeu)
Cependant, si vous voulez un index, vous devez renvoyer un INDEX réel et non un Int, car une valeur Int nécessiterait des étapes supplémentaires pour toute utilisation pratique. Ces extensions renvoient un index, un décompte d'un caractère spécifique et une plage que ce code plug-in capable de jeu va démontrer.
la source
Solution complète Swift 4:
OffsetIndexableCollection (chaîne utilisant l'index Int)
https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-
la source
extension String {
}
la source
Swift 5
Trouver l'index de la sous-chaîne
Trouver l'index du personnage
la source
Si vous cherchez un moyen facile d'obtenir l'index des caractères ou des chaînes, consultez cette bibliothèque http://www.dollarswift.org/#indexof-char-character-int
Vous pouvez obtenir l'indexOf d'une chaîne en utilisant également une autre chaîne ou un modèle d'expression régulière
la source
Pour obtenir l'index d'une sous-chaîne dans une chaîne avec Swift 2:
la source
Dans swift 2.0
la source
la source
Je joue avec les suivants
jusqu'à ce que je comprenne celui fourni maintenant c'est juste un tableau de caractères
et avec
la source
Si vous n'avez besoin que de l'index d'un caractère, la solution la plus simple et rapide (comme déjà souligné par Pascal) est:
la source
Au sujet de transformer un
String.Index
en unInt
, cette extension fonctionne pour moi:Exemple d'utilisation correspondant à cette question:
Important:
Comme vous pouvez le constater, il regroupe les grappes de graphèmes étendues et les caractères joints différemment de
String.Index
. Bien sûr, c'est pourquoi nous l'avons faitString.Index
. Vous devez garder à l'esprit que cette méthode considère les clusters comme des caractères singuliers, ce qui est plus proche de la correction. Si votre objectif est de diviser une chaîne par point de code Unicode, ce n'est pas la solution pour vous.la source
Dans Swift 2.0 , la fonction suivante renvoie une sous-chaîne avant un caractère donné.
la source
Vous pouvez trouver le numéro d'index d'un caractère dans une chaîne avec ceci:
la source
Comme mon point de vue, la meilleure façon de connaître la logique elle-même est ci-dessous
la source