Ottieni la lunghezza di una stringa


780

Come si ottiene la lunghezza di un String? Ad esempio, ho una variabile definita come:

var test1: String = "Scott"

Tuttavia, non riesco a trovare un metodo di lunghezza sulla stringa.


possibile duplicato della lunghezza
King-Wizard

Ho dovuto migrare molto codice manualmente a causa di Swift 3. Quindi ho deciso di creare estensioni. Quindi ora, se devo passare a una nuova versione principale, devo migrare solo l'estensione. Qui puoi trovare alcune estensioni di Swift 3 che ho creato. github.com/tukur187/Swift3
Shkelzen

Risposte:


1284

A partire da Swift 4+

È appena:

test1.count

per ragioni.

(Grazie a Martin R)

A partire da Swift 2:

Con Swift 2, Apple ha modificato le funzioni globali in estensioni di protocollo, estensioni che corrispondono a qualsiasi tipo conforme a un protocollo. Quindi la nuova sintassi è:

test1.characters.count

(Grazie a JohnDifool per l'heads up)

A partire da Swift 1

Utilizzare il metodo conteggio caratteri:

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

direttamente dalla Apple Swift Guide

(nota, per le versioni di Swift precedenti alla 1.2, questo sarebbe countElements(unusualMenagerie)invece)

per la tua variabile, sarebbe

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

Oppure puoi usare test1.utf16count


11
Interessante che countElements sia una funzione globale. Esiste un elenco di funzioni globali?
Scott Walter,

7
Il problema con countElements è che viene dichiarato in questo modo: func countElements <T> (x: T) -> T.IndexType.DistanceType e il tipo restituito non accetta l'operazione +.
Marco Aurelio,

288
Era troppo difficile aggiungere un metodo str.length. (alza il pugno con rabbia)
botbot,

13
Con Swift 2, riesco solo a farlo funzionare: let len ​​= test1.characters.count
Laurent,

7
Nota che con Swift 4 lo sarà string.count.
Martin R,

335

TLDR:

Per Swift 2.0 e 3.0, utilizzaretest1.characters.count . Ma ci sono alcune cose che dovresti sapere. Quindi, continua a leggere.

Conteggio dei personaggi in Swift

Prima di Swift 2.0, countera una funzione globale. A partire da Swift 2.0, può essere chiamato come funzione membro.

test1.characters.count

Restituirà il numero effettivo di caratteri Unicode in a String, quindi è l'alternativa più corretta nel senso che, se stampassi la stringa e contassi i caratteri a mano, otterrai lo stesso risultato.

Tuttavia, a causa del modo in cui Stringssono implementati in Swift, i personaggi non occupano sempre la stessa quantità di memoria, quindi tieni presente che ciò si comporta in modo abbastanza diverso rispetto ai soliti metodi di conteggio dei caratteri in altre lingue.

Ad esempio, puoi anche usare test1.utf16.count

Ma, come indicato di seguito, il valore restituito non è garantito per essere la stessa di quella di chiamare countsu characters.

Dal riferimento linguistico:

I cluster grapheme estesi possono essere composti da uno o più scalari Unicode. Ciò significa che caratteri diversi - e diverse rappresentazioni dello stesso personaggio - possono richiedere diverse quantità di memoria per essere archiviati. Per questo motivo, i personaggi di Swift non occupano ciascuno la stessa quantità di memoria all'interno della rappresentazione di una stringa. Di conseguenza, il numero di caratteri in una stringa non può essere calcolato senza iterare attraverso la stringa per determinare i limiti estesi del cluster grapheme. Se si lavora con valori di stringa particolarmente lunghi, tenere presente che la proprietà caratteri deve scorrere tra gli scalari Unicode nell'intera stringa per determinare i caratteri per quella stringa.

Il conteggio dei caratteri restituiti dalla proprietà characters non è sempre uguale alla proprietà length di una NSString che contiene gli stessi caratteri. La lunghezza di una NSString si basa sul numero di unità di codice a 16 bit all'interno della rappresentazione UTF-16 della stringa e non sul numero di cluster grapheme estesi Unicode all'interno della stringa.

Un esempio che illustra perfettamente la situazione sopra descritta è quello di controllare la lunghezza di una stringa contenente un singolo carattere emoji, come sottolineato da n00neimp0rtant nei commenti.

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

26
Apprezzo la tua risposta dettagliata e cautelativa, ma devo ammettere che mi ha lasciato a disagio. Mi hai dato 3 modi per ottenere la lunghezza di una stringa, il tutto con il disclaimer che le risposte che danno potrebbero non essere quello che ti aspetti. In Swift non esiste davvero un modo affidabile per ottenere un valore di lunghezza preciso e affidabile di una stringa?
n00neimp0rtant,

6
@ n00neimp0rtant. Scusa se non l'ho chiarito. La prima soluzione ( countElements()) ottiene il numero esatto di caratteri nella stringa. Potrebbe essere diverso da quello che otterresti dalla chiamata [str length]in Objective-C, perché il lengthmetodo presuppone che tutti i caratteri nella stringa siano composti da unità di codice a 16 bit, mentre countElements()ottiene il numero effettivo di caratteri Unicode. Tuttavia, la maggior parte delle alternative di cui sopra restituirà gli stessi risultati, specialmente se stai lavorando con caratteri comuni in lingua inglese.
Cezar,

2
@ n00neimp0rtant Ho modificato un po 'la mia risposta per provare a renderlo più chiaro.
Cezar,

2
Capisco cosa intendi adesso. Ho appena provato a ottenere la lunghezza di una stringa contenente un singolo carattere Emoji; Objective-C mi ha dato un valore di 4 e Swift mi ha dato un valore di 1. Quindi in realtà sembra più preciso (e quindi, ironicamente, "non quello che mi aspetterei" = P). Grazie per il chiarimento!
n00neimp0rtant,

1
@ n00neimp0rtant Esattamente! Questo è un esempio perfetto. Lo aggiungerò anche alla risposta
Cezar,

92

Aggiornamento Swift 1.2: non esiste più un countElements per il conteggio delle dimensioni delle raccolte. Basta usare la funzione count come sostituto: count ("Swift")

Swift 2.0, 3.0 e 3.1:

let strLength = string.characters.count

Swift 4.2 (4.0 in poi): [Documentazione Apple - Stringhe]

let 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    }  // 
}

Rapido 4.2

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

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

6
Sì, abbiamo bisogno di un livello di astrazione per la sintassi di Swift che sta cambiando su base mensile!
Cosmin

@Lee Questo non funziona in swift 4. poiché i personaggi sono deprecati. Continua la corsa alla talpa. sospiro
eonista

48

Swift 4

"string".count

;)

Swift 3

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

uso

"string".length


Restituisce String.CharacterView.IndexDistance. Che dire di Int?
eonista

@GitSync dove? Non ti capisco
Vyacheslav,

@Vyacheslav in swift 4 "string" .count restituisce String.CharacterView.IndexDistance Vedi la mia risposta qui: stackoverflow.com/a/47203597/5389500 per ottenere int in rapido 3 e 4
eonista

Ho testato questo è il parco giochi:
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

Se stai solo cercando di vedere se una stringa è vuota o meno (controllando la lunghezza di 0), Swift offre un semplice metodo di test booleano su String

myString.isEmpty

L'altro lato di questa moneta era la gente che chiedeva in ObjectiveC come chiedere se una stringa era vuota dove la risposta doveva controllare per una lunghezza di 0:

NSString è vuoto


18

tl; dr Se vuoi la lunghezza di un tipo String in termini di numero di caratteri leggibili dall'uomo, usa countElements () . Se vuoi conoscere la lunghezza in termini di numero di cluster grapheme estesi , usa endIndex . Continua a leggere per i dettagli.

La stringa tipo è implementato come un insieme ordinato (cioè, la sequenza) di caratteri Unicode, e conforme al CollectionType protocollo, che è conforme alla _CollectionType protocollo, che è il tipo input atteso da countElements () . Pertanto, countElements () può essere chiamato, passando un tipo String , e restituirà il conteggio dei caratteri.

Tuttavia, in conformità a CollectionType , che a sua volta è conforme a _CollectionType , String implementa anche le proprietà calcolate startIndex ed endIndex , che in realtà rappresentano la posizione dell'indice prima del primo cluster di caratteri e la posizione dell'indice dopo l'ultimo cluster di caratteri, rispettivamente . Quindi, nella stringa "ABC", la posizione dell'indice prima di A è 0 e dopo C è 3. Pertanto, endIndex = 3, che è anche la lunghezza della stringa.

Quindi, endIndex può essere utilizzato per ottenere la lunghezza di qualsiasi tipo di stringa, quindi, giusto?

Beh, non sempre ... I personaggi Unicode sono in realtà cluster estesi di grapheme , che sono sequenze di uno o più scalari Unicode combinati per creare un singolo personaggio leggibile dall'uomo.

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

cercledStar è un singolo personaggio composto da U + 2606 (una stella bianca) e U + 20DD (un cerchio che racchiude la combinazione). Creiamo una stringa da circledStar e confrontiamo i risultati di countElements () e endIndex .

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

15

In Swift 2.0 countnon funziona più. È possibile utilizzare questo invece:

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

14

Ecco qualcosa di più breve e più naturale dell'utilizzo di una funzione globale:

aString.utf16count

Non so se sia disponibile in beta 1, però. Ma è sicuramente lì in beta 2.


2
Vedi la risposta di Cezar. Questo non ti darà necessariamente il numero di "caratteri" nella stringa, per la definizione di "carattere" della maggior parte delle persone. D'altra parte, nemmeno Objective-C - sta a te decidere se ti interessa o no.
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

Aggiornato per Xcode 6 beta 4, cambia metodo utf16count -> utf16Count

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

O

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

Quando stai usando stringhe complesse con emoji, la risposta con utf16countsarà sbagliata
Victor Sigler

10

A partire da Swift 1.2 utf16Countè stato rimosso. Ora dovresti usare la count()funzione globale e passare la vista UTF16 della stringa. Esempio sotto ...

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

1
È più lento di .utf16count?
samir105

1
Sembra la stessa velocità di .utf16count, molto più veloce del conteggio (stringa)
samir105

8

Per Xcode 7.3 e Swift 2.2.

let str = "🐶"
  1. Se vuoi il numero di caratteri visivi:

    str.characters.count
  2. Se si desidera "Unità di codice a 16 bit all'interno della rappresentazione UTF-16 della stringa":

    str.utf16.count

Il più delle volte, 1 è quello che ti serve.

Quando avresti bisogno di 2 ? Ho trovato un caso d'uso per 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

Se si utilizza 1 , il risultato non è corretto:

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

7

Potresti provare così

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

4
È lo stesso ditest1.utf16count
Sulthan,

1
@vladof bene, "tipo di" funziona. Vedi la risposta di Cezar.
jbg

6

in Swift 2.x il seguente è come trovare la lunghezza di una stringa

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

restituisce 24


5

Swift 2.0: Ottieni un conteggio: yourString.text.characters.count

Un esempio divertente di come questo sarebbe utile sarebbe mostrare un conto alla rovescia di un personaggio da un numero (ad esempio 150) in un UITextView:

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

4

In swift4 l'ho sempre usato string.countfino ad oggi, l'ho scoperto

string.endIndex.encodedOffset

è la sostituzione migliore perché è più veloce - per 50.000 caratteri la stringa è circa 6 volte più veloce di .count. La .countdipende dalla lunghezza della stringa, ma .endIndex.encodedOffsetnon lo fa.

Ma c'è un NO. Non è buono per le stringhe con emoji, darà risultati errati, quindi .countè solo corretto.


3

In Swift 4 : Se la stringa non contiene caratteri unicode, utilizza quanto segue

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

Se la stringa contiene caratteri unicode, utilizzare quanto segue:

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

Perché vorresti usare utf8.count? Ciò non indica il conteggio dei personaggi. Fornisce il numero di byte necessari per la codifica UTF-8 della stringa.
rmaddy,

2

In Xcode 6.1.1

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

Penso che i cervelletti cambieranno questo in ogni versione minore.


2

Ottieni il valore di stringa dalla visualizzazione di testo o dal campo di testo:

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

Trova il conteggio dei caratteri nella stringa:

let numberOfChars = textlength.characters.count

2

Ecco cosa ho finito per fare

let replacementTextAsDecimal = Double(string)

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

Penso che tu stia cercando di fare di più che ottenere la lunghezza della stringa, e in ogni caso questo sembra incompleto (non dovrebbe esserci anche un return truecaso?). Puoi per favore ricontrollare e, nel caso, modificare la tua risposta? Grazie!
Fabio dice di reintegrare Monica il

2

Aggiornamento di Swift 4 rispetto a swift 3

Swift 4 elimina la necessità di un array di caratteri su String. Ciò significa che è possibile chiamare direttamente countuna stringa senza ottenere prima l'array di caratteri.

"hello".count                  // 5

Considerando che in Swift 3, dovrai ottenere l'array di caratteri e quindi contare l'elemento in quell'array. Si noti che questo metodo seguente è ancora disponibile in Swift 4.0 poiché è ancora possibile chiamare charactersper accedere all'array di caratteri della stringa specificata

"hello".characters.count       // 5

Swift 4.0 adotta anche Unicode 9 e ora è in grado di interpretare i cluster grapheme. Ad esempio, contare su un'emoji ti darà 1 mentre in swift 3.0 potresti ottenere conteggi maggiori di 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 

Ricorda: anche lo spazio viene contato nel numero


2

Puoi ottenere la lunghezza semplicemente scrivendo un'estensione:

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)

Questo conta i caratteri nella Regular Swift String

countElements((newString as String))    

Questo conta i caratteri in un NSString


1

Il modo migliore per contare String in Swift è questo:

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

2
Dovresti usare solo count (str). Prova a usare count (str.utf16) con anticipo sotto stringa ()
Leo Dabus

1

String e NSString sono bridge gratuiti quindi è possibile utilizzare tutti i metodi disponibili per NSString con String veloce

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

1
test1.characters.count

ti darà il numero di lettere / numeri ecc. nella tua stringa.

ex:

test1 = "StackOverflow"

print(test1.characters.count)

( stampa " 13 ")


1

Apple lo ha reso diverso dall'altra lingua principale. Il modo attuale è chiamare:

test1.characters.count

Tuttavia, per fare attenzione, quando dici lunghezza intendi il conteggio dei caratteri e non il conteggio dei byte, perché quei due possono essere diversi quando usi caratteri non ascii.

Per esempio; "你好啊hi".characters.countti darà 5 ma questo non è il conteggio dei byte. Per ottenere il conteggio reale dei byte, devi farlo "你好啊hi".lengthOfBytes(using: String.Encoding.utf8). Questo ti darà 11.


1

In questo momento (in Swift 2.3) se usi:

myString.characters.count 

il metodo restituirà un tipo "Distanza", se hai bisogno del metodo per restituire un numero intero devi digitare cast in questo modo:

var count = myString.characters.count as Int

2
Il Distancedi String.CharacterView è Int , non dovrebbe esserci bisogno di questo cast.
Martin R
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.