Obtenez la longueur d'une chaîne


780

Comment obtenez-vous la longueur d'un String? Par exemple, j'ai une variable définie comme:

var test1: String = "Scott"

Cependant, je n'arrive pas à trouver une méthode de longueur sur la chaîne.


doublon possible de la longueur
King-Wizard

J'ai dû migrer beaucoup de code manuellement à cause de Swift 3. J'ai donc décidé de créer des extensions. Alors maintenant, si je dois passer à une nouvelle version majeure, je dois migrer uniquement l'extension. Ici vous pouvez trouver quelques extensions Swift 3 que j'ai créées. github.com/tukur187/Swift3
Shkelzen

Réponses:


1284

À partir de Swift 4+

C'est juste:

test1.count

pour des raisons.

(Merci à Martin R)

Depuis Swift 2:

Avec Swift 2, Apple a changé les fonctions globales en extensions de protocole, extensions qui correspondent à tout type conforme à un protocole. Ainsi, la nouvelle syntaxe est:

test1.characters.count

(Merci à JohnDifool pour l'avertissement)

À partir de Swift 1

Utilisez la méthode du nombre de caractères:

let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
println("unusualMenagerie has \(count(unusualMenagerie)) characters")
// prints "unusualMenagerie has 40 characters"

directement depuis le Guide Apple Swift

(notez que pour les versions de Swift antérieures à 1.2, ce serait countElements(unusualMenagerie)plutôt)

pour votre variable, ce serait

length = count(test1) // was countElements in earlier versions of Swift

Ou vous pouvez utiliser test1.utf16count


11
Il est intéressant de noter que countElements est une fonction globale. Existe-t-il une liste de fonctions globales?
Scott Walter

7
Le problème avec countElements est qu'il est déclaré comme ceci: func countElements <T> (x: T) -> T.IndexType.DistanceType et le type de retour n'accepte pas l'opération +.
MarkAurelius

288
Il était tout simplement trop difficile d'ajouter une méthode str.length. (lève le poing de colère)
botbot

13
Avec Swift 2, je ne peux que faire fonctionner ceci: let len ​​= test1.characters.count
Laurent

7
Notez qu'avec Swift 4, ce sera le cas string.count.
Martin R

335

TLDR:

Pour Swift 2.0 et 3.0, utiliseztest1.characters.count . Mais, il y a quelques choses que vous devez savoir. Alors, lisez la suite.

Compter les caractères dans Swift

Avant Swift 2.0, countétait une fonction globale. Depuis Swift 2.0, il peut être appelé en tant que fonction membre.

test1.characters.count

Il renverra le nombre réel de caractères Unicode dans a String, c'est donc l'alternative la plus correcte dans le sens où, si vous imprimiez la chaîne et comptiez les caractères à la main, vous obtiendriez le même résultat.

Cependant, en raison de la façon dont ils Stringssont implémentés dans Swift, les caractères n'occupent pas toujours la même quantité de mémoire, alors sachez que cela se comporte assez différemment des méthodes de comptage de caractères habituelles dans d'autres langues.

Par exemple, vous pouvez également utiliser test1.utf16.count

Mais, comme il est indiqué ci - dessous, la valeur retournée est pas garanti d'être le même que celui d'appeler countlecharacters .

De la référence de langue:

Les grappes de graphèmes étendues peuvent être composées d'un ou plusieurs scalaires Unicode. Cela signifie que différents caractères et différentes représentations du même caractère peuvent nécessiter différentes quantités de mémoire pour être stockées. Pour cette raison, les caractères dans Swift n'occupent pas chacun la même quantité de mémoire dans la représentation d'une chaîne. Par conséquent, le nombre de caractères d'une chaîne ne peut pas être calculé sans parcourir la chaîne pour déterminer ses limites étendues de grappe de graphèmes. Si vous travaillez avec des valeurs de chaîne particulièrement longues, sachez que la propriété caractères doit itérer sur les scalaires Unicode de la chaîne entière afin de déterminer les caractères de cette chaîne.

Le nombre de caractères renvoyés par la propriété caractères n'est pas toujours le même que la propriété de longueur d'une NSString qui contient les mêmes caractères. La longueur d'une chaîne NSS est basée sur le nombre d'unités de code 16 bits dans la représentation UTF-16 de la chaîne et non sur le nombre de grappes de graphèmes étendus Unicode dans la chaîne.

Un exemple qui illustre parfaitement la situation décrite ci-dessus est celui de la vérification de la longueur d'une chaîne contenant un seul caractère emoji, comme indiqué par n00neimp0rtant dans les commentaires.

var emoji = "👍"
emoji.characters.count             //returns 1
emoji.utf16.count                  //returns 2

26
J'apprécie votre réponse détaillée et prudente, mais je dois admettre que cela me laisse mal à l'aise. Vous m'avez donné 3 façons d'obtenir la longueur d'une chaîne, le tout avec l'avertissement que les réponses qu'elles donnent pourraient ne pas être ce que vous attendez. Existe-t-il vraiment aucun moyen fiable intégré à Swift pour obtenir une valeur de longueur précise et fiable d'une chaîne?
n00neimp0rtant

6
@ n00neimp0rtant. Désolé si je n'ai pas été clair. La première solution ( countElements()) obtient le nombre exact de caractères dans la chaîne. Cela peut être différent de ce que vous obtiendriez en appelant [str length]dans Objective-C, car la lengthméthode suppose que tous les caractères de la chaîne sont composés d'unités de code 16 bits, tout en countElements()obtenant le nombre réel de caractères Unicode. Cependant, la plupart du temps, toutes les alternatives ci-dessus retourneront les mêmes résultats, surtout si vous travaillez avec des caractères communs en anglais.
Cezar

2
@ n00neimp0rtant J'ai légèrement modifié ma réponse pour essayer de la rendre plus claire.
Cezar

2
Je comprends ce que tu veux dire maintenant. J'ai juste essayé d'obtenir la longueur d'une chaîne contenant un seul caractère Emoji; Objective-C m'a donné une valeur de 4 et Swift m'a donné une valeur de 1. Donc, cela semble en fait plus précis (et donc, ironiquement "pas ce à quoi je m'attendais" = P). Merci pour la clarification!
n00neimp0rtant

1
@ n00neimp0rtant Exactement! Voilà un parfait exemple. Je vais même l'ajouter à la réponse
Cezar

92

Mise à jour Swift 1.2: il n'y a plus de countElements pour compter la taille des collections. Utilisez simplement la fonction count comme remplacement: count ("Swift")

Swift 2.0, 3.0 et 3.1:

laissez strLength = string.characters.count

Swift 4.2 (à partir de 4.0): [Documentation Apple - Chaînes]

laissez strLength = string.count


61

Swift 1.1

extension String {
    var length: Int { return countElements(self) }  // 
}

Swift 1.2

extension String {
    var length: Int { return count(self)         }  // 
}

Swift 2.0

extension String {
    var length: Int { return characters.count    }  // 
}

Swift 4.2

extension String {
    var length: Int { return self.count }           
}

let str = "Hello"
let count = str.length    // returns 5 (Int)

6
Oui, nous avons besoin d'une couche d'abstraction pour la syntaxe de Swift qui change tous les mois!
Cosmin

@Lee Cela ne fonctionne pas dans swift 4. car les caractères sont dépréciés. La course de whac-a-mole continue. soupir
éoniste

48

Swift 4

"string".count

;)

Swift 3

extension String {
    var length: Int {
        return self.characters.count
    }
}

usage

"string".length


Il renvoie String.CharacterView.IndexDistance. Et Int?
eonist

@GitSync où? Je ne te comprends pas
Vyacheslav

@Vyacheslav dans swift 4 "string" .count renvoie String.CharacterView.IndexDistance Voir ma réponse ici: stackoverflow.com/a/47203597/5389500 pour obtenir l'int dans swift 3 et 4
eonist

J'ai testé c'est le terrain de jeu:
Vyacheslav

//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground" print(type(of: str.characters.count)) print(type(of: str.count))
Vyacheslav

25

Si vous essayez simplement de voir si une chaîne est vide ou non (vérification de la longueur de 0), Swift propose une méthode de test booléenne simple sur String

myString.isEmpty

L'autre côté de cette pièce était des gens qui demandaient dans ObjectiveC comment demander si une chaîne était vide où la réponse devait vérifier une longueur de 0:

NSString est vide


18

tl; dr Si vous voulez la longueur d'un type String en termes de nombre de caractères lisibles par l'homme, utilisez countElements () . Si vous voulez connaître la longueur en termes de nombre de grappes de graphèmes étendus , utilisez endIndex . Lisez la suite pour plus de détails.

Le type String est implémenté comme une collection ordonnée (c'est-à-dire une séquence) de caractères Unicode, et il est conforme au protocole CollectionType , qui est conforme au protocole _CollectionType , qui est le type d'entrée attendu par countElements () . Par conséquent, countElements () peut être appelé, en passant un type String , et il renverra le nombre de caractères.

Cependant, en se conformant à CollectionType , qui à son tour est conforme à _CollectionType , String implémente également les propriétés calculées startIndex et endIndex , qui représentent en fait la position de l'index avant le premier cluster de caractères et la position de l'index après le dernier cluster de caractères, respectivement . Ainsi, dans la chaîne "ABC", la position de l'index avant A est 0 et après C est 3. Par conséquent, endIndex = 3, qui est également la longueur de la chaîne.

Ainsi, endIndex peut être utilisé pour obtenir la longueur de tout type de chaîne, alors, non?

Eh bien, pas toujours ... Les caractères Unicode sont en fait des grappes de graphèmes étendus , qui sont des séquences d'un ou plusieurs scalaires Unicode combinés pour créer un seul caractère lisible par l'homme.

let circledStar: Character = "\u{2606}\u{20DD}" // ☆⃝

circledStar est un caractère unique composé de U + 2606 (une étoile blanche) et U + 20DD (un cercle englobant combinant). Créons une chaîne à partir de circledStar et comparons les résultats de countElements () et endIndex .

let circledStarString = "\(circledStar)"
countElements(circledStarString) // 1
circledStarString.endIndex // 2

15

Dans Swift 2.0 countne fonctionne plus. Vous pouvez utiliser ceci à la place:

var testString = "Scott"
var length = testString.characters.count

14

Voici quelque chose de plus court et de plus naturel que d'utiliser une fonction globale:

aString.utf16count

Cependant, je ne sais pas s'il est disponible en version bêta 1. Mais c'est définitivement là dans la bêta 2.


2
Voir la réponse de Cezar. Cela ne vous donnera pas nécessairement le nombre de «caractères» dans la chaîne, pour la définition de «caractère» de la plupart des gens. Là encore, Objective-C non plus - c'est à vous de décider si vous vous souciez ou non.
jbg

12

Swift 5.1, 5

let flag = "🇵🇷"

print(flag.count)
// Prints "1" --  Counts the characters and emoji as length 1

print(flag.unicodeScalars.count)
// Prints "2" --  Counts the unicode lenght ex. "A" is 65

print(flag.utf16.count)
// Prints "4"

print(flag.utf8.count)
// Prints "8"

11

Mis à jour pour Xcode 6 beta 4, changez la méthode utf16count -> utf16Count

 var test1: String = "Scott"
 var length =  test1.utf16Count

Ou

 var test1: String = "Scott"
 var length = test1.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)

Lorsque vous utilisez des chaînes complexes avec des emoji, la réponse utf16countsera fausse
Victor Sigler

10

À partir de Swift 1.2 utf16Counta été supprimé. Vous devez maintenant utiliser la count()fonction globale et passer la vue UTF16 de la chaîne. Exemple ci-dessous ...

let string = "Some string"
count(string.utf16)

1
Est-ce plus lent que .utf16count?
samir105

1
Il semble avoir la même vitesse que .utf16count, beaucoup plus rapide que count (string)
samir105

8

Pour Xcode 7.3 et Swift 2.2.

let str = "🐶"
  1. Si vous voulez le nombre de caractères visuels:

    str.characters.count
  2. Si vous voulez les "unités de code 16 bits dans la représentation UTF-16 de la chaîne":

    str.utf16.count

La plupart du temps, 1 est ce dont vous avez besoin.

Quand auriez-vous besoin de 2 ? J'ai trouvé un cas d'utilisation pour 2 :

let regex = try! NSRegularExpression(pattern:"🐶", 
    options: NSRegularExpressionOptions.UseUnixLineSeparators)
let str = "🐶🐶🐶🐶🐶🐶"
let result = regex.stringByReplacingMatchesInString(str, 
    options: NSMatchingOptions.WithTransparentBounds, 
    range: NSMakeRange(0, str.utf16.count), withTemplate: "dog")
print(result) // dogdogdogdogdogdog

Si vous utilisez 1 , le résultat est incorrect:

let result = regex.stringByReplacingMatchesInString(str, 
    options: NSMatchingOptions.WithTransparentBounds, 
    range: NSMakeRange(0, str.characters.count), withTemplate: "dog")
print(result) // dogdogdog🐶🐶🐶

7

Tu pourrais essayer comme ça

var test1: String = "Scott"
var length =  test1.bridgeToObjectiveC().length

4
C'est la même chose quetest1.utf16count
Sulthan

1
@vladof bien, ça "fonctionne". Voir la réponse de Cezar.
jbg

6

dans Swift 2.x, voici comment trouver la longueur d'une chaîne

let findLength = "This is a string of text"
findLength.characters.count

renvoie 24


5

Swift 2.0: Obtenez un décompte: yourString.text.characters.count

Un exemple amusant de la façon dont cela est utile serait d'afficher un compte à rebours de caractères à partir d'un certain nombre (150 par exemple) dans un UITextView:

func textViewDidChange(textView: UITextView) {
    yourStringLabel.text = String(150 - yourStringTextView.text.characters.count)
}

4

Dans swift4, j'ai toujours utilisé string.countjusqu'à aujourd'hui, j'ai trouvé que

string.endIndex.encodedOffset

est la meilleure substitution car elle est plus rapide - pour 50 000 caractères, la chaîne est environ 6 fois plus rapide que .count. Cela .countdépend de la longueur de la chaîne, mais .endIndex.encodedOffsetpas.

Mais il y a un NON. Ce n'est pas bon pour les cordes avec des emojis, cela donnera un mauvais résultat, donc seul .countest correct.


3

Dans Swift 4 : si la chaîne ne contient pas de caractères unicode, utilisez ce qui suit

let str : String = "abcd"
let count = str.count // output 4

Si la chaîne contient des caractères unicode, utilisez ce qui suit:

let spain = "España"
let count1 = spain.count // output 6
let count2 = spain.utf8.count // output 7

Pourquoi voudriez-vous utiliser utf8.count? Cela ne donne pas le nombre de caractères. Il donne le nombre d'octets nécessaires pour le codage UTF-8 de la chaîne.
rmaddy

2

Dans Xcode 6.1.1

extension String {    
    var length : Int { return self.utf16Count  }
}

Je pense que les brainiacs changeront cela sur chaque version mineure.


2

Obtenez la valeur de chaîne de votre textview ou textfield:

let textlengthstring = (yourtextview?.text)! as String

Trouvez le nombre de caractères dans la chaîne:

let numberOfChars = textlength.characters.count

2

Voici ce que j'ai fini par faire

let replacementTextAsDecimal = Double(string)

if string.characters.count > 0 &&
    replacementTextAsDecimal == nil &&
    replacementTextHasDecimalSeparator == nil {
        return false
}

Je pense que vous essayez de faire plus que simplement obtenir la longueur de la chaîne, et en tout cas cela semble incomplet (ne devrait-il pas y avoir aussi un return truecas?). Pouvez-vous s'il vous plaît revérifier et, au cas où, modifier votre réponse? Je vous remercie!
Fabio dit Réintégrer Monica le

2

Mise à jour de Swift 4 comparant avec Swift 3

Swift 4 supprime le besoin d'un tableau de caractères sur String. Cela signifie que vous pouvez appeler directement countune chaîne sans obtenir de tableau de caractères au préalable.

"hello".count                  // 5

Alors que dans swift 3, vous devrez obtenir un tableau de caractères, puis compter l'élément dans ce tableau. Notez que cette méthode suivante est toujours disponible dans swift 4.0 car vous pouvez toujours appeler characterspour accéder au tableau de caractères de la chaîne donnée

"hello".characters.count       // 5

Swift 4.0 adopte également Unicode 9 et il peut désormais interpréter les grappes de graphèmes. Par exemple, compter sur un emoji vous donnera 1 tandis que dans swift 3.0, vous pouvez obtenir un nombre supérieur à 1.

"👍🏽".count // Swift 4.0 prints 1, Swift 3.0 prints 2
"👨‍❤️‍💋‍👨".count // Swift 4.0 prints 1, Swift 3.0 prints 4

2

Swift 4

let str =  "Your name"

str.count 

N'oubliez pas: l'espace est également compté dans le nombre


2

Vous pouvez obtenir la longueur simplement en écrivant une extension:

extension String {
    // MARK: Use if it's Swift 2
    func stringLength(str: String) -> Int {
        return str.characters.count
    }

    // MARK: Use if it's Swift 3
    func stringLength(_ str: String) -> Int {
        return str.characters.count
    }

    // MARK: Use if it's Swift 4
    func stringLength(_ str: String) -> Int {
        return str.count
    }
}

1
var str = "Hello, playground"
var newString = str as NSString    

countElements(str)

Cela compte les caractères de la chaîne Swift régulière

countElements((newString as String))    

Cela compte les caractères dans une chaîne NSS


1

La meilleure façon de compter String dans Swift est la suivante:

var str = "Hello World"
var length = count(str.utf16)

2
Vous devez utiliser simplement count (str). Essayez d'utiliser le nombre (str.utf16) avec une avance de sous-chaîne ()
Leo Dabus

1

String et NSString sont des ponts gratuits afin que vous puissiez utiliser toutes les méthodes disponibles pour NSString avec swift String

let x = "test" as NSString
let y : NSString = "string 2"
let lenx = x.count
let leny = y.count

1
test1.characters.count

vous obtiendrez le nombre de lettres / chiffres, etc. dans votre chaîne.

ex:

test1 = "StackOverflow"

print(test1.characters.count)

( imprime " 13 ")


1

Apple l'a rendu différent des autres langues principales. La méthode actuelle consiste à appeler:

test1.characters.count

Cependant, pour être prudent, lorsque vous dites longueur, vous entendez le nombre de caractères et non le nombre d'octets, car ces deux peuvent être différents lorsque vous utilisez des caractères non ascii.

Par exemple; "你好啊hi".characters.countvous donnera 5 mais ce n'est pas le nombre d'octets. Pour obtenir le nombre réel d'octets, vous devez le faire "你好啊hi".lengthOfBytes(using: String.Encoding.utf8). Cela vous donnera 11.


1

En ce moment (dans Swift 2.3) si vous utilisez:

myString.characters.count 

la méthode retournera un type "Distance", si vous avez besoin de la méthode pour retourner un entier, vous devez taper cast comme ceci:

var count = myString.characters.count as Int

2
Le Distanceof String.CharacterView est Int , il ne devrait pas être nécessaire pour cette distribution.
Martin R
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.