Holen Sie sich die Länge eines Strings


781

Wie bekommt man die Länge eines String? Zum Beispiel habe ich eine Variable definiert wie:

var test1: String = "Scott"

Ich kann jedoch keine Längenmethode für die Zeichenfolge finden.



Aufgrund von Swift 3 musste ich viel Code manuell migrieren. Deshalb habe ich beschlossen, Erweiterungen zu erstellen. Wenn ich jetzt auf eine neue Hauptversion aktualisieren muss, muss ich nur die Erweiterung migrieren. Hier finden Sie einige von mir erstellte Swift 3-Erweiterungen. github.com/tukur187/Swift3
Shkelzen

Antworten:


1284

Ab Swift 4+

Es ist nur:

test1.count

auf Grund.

(Danke an Martin R)

Ab Swift 2:

Mit Swift 2 hat Apple globale Funktionen in Protokollerweiterungen geändert, Erweiterungen, die jedem Typ entsprechen, der einem Protokoll entspricht. Die neue Syntax lautet also:

test1.characters.count

(Danke an JohnDifool für das Heads Up)

Ab Swift 1

Verwenden Sie die Methode zum Zählen von Zeichen:

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

direkt aus dem Apple Swift Guide

(Beachten Sie, dass dies für Versionen von Swift vor 1.2 countElements(unusualMenagerie)stattdessen der Fall ist. )

für Ihre Variable wäre es

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

Oder Sie können test1.utf16count verwenden


11
Interessant, dass countElements eine globale Funktion ist. Gibt es eine Liste globaler Funktionen?
Scott Walter

7
Das Problem mit countElements besteht darin, dass es wie folgt deklariert wird: func countElements <T> (x: T) -> T.IndexType.DistanceType und der Rückgabetyp akzeptieren die Operation + nicht.
MarkAurelius

288
Es war einfach zu schwierig, eine str.length-Methode hinzuzufügen. (hebt
wütend

13
Mit Swift 2 kann ich das nur zum Laufen bringen: let len ​​= test1.characters.count
Laurent

7
Beachten Sie, dass dies bei Swift 4 der Fall sein wird string.count.
Martin R

335

TLDR:

Verwenden Sie für Swift 2.0 und 3.0test1.characters.count . Aber es gibt ein paar Dinge, die Sie wissen sollten. Also lesen Sie weiter.

Zeichen in Swift zählen

Vor Swift 2.0 countwar eine globale Funktion. Ab Swift 2.0 kann es als Member-Funktion aufgerufen werden.

test1.characters.count

Es wird die tatsächliche Anzahl von Unicode-Zeichen in a zurückgegeben String. Dies ist die korrekteste Alternative in dem Sinne, dass Sie das gleiche Ergebnis erhalten, wenn Sie die Zeichenfolge drucken und die Zeichen von Hand zählen.

Aufgrund der Art und Weise, Stringswie sie in Swift implementiert sind, belegen Zeichen nicht immer die gleiche Speichermenge. Beachten Sie daher, dass sich dies ganz anders verhält als die üblichen Methoden zur Zeichenanzahl in anderen Sprachen.

Zum Beispiel können Sie auch verwenden test1.utf16.count

Aber, wie unten erwähnt, ist der zurückgegebene Wert nicht garantiert die gleiche sein wie die der Aufruf countauf characters.

Aus der Sprachreferenz:

Erweiterte Graphemcluster können aus einem oder mehreren Unicode-Skalaren bestehen. Dies bedeutet, dass unterschiedliche Zeichen - und unterschiedliche Darstellungen desselben Zeichens - unterschiedliche Speichermengen zum Speichern erfordern können. Aus diesem Grund belegen Zeichen in Swift nicht jeweils dieselbe Speichermenge in der Darstellung einer Zeichenfolge. Infolgedessen kann die Anzahl der Zeichen in einer Zeichenfolge nicht berechnet werden, ohne die Zeichenfolge zu durchlaufen, um die erweiterten Grenzen des Graphemclusters zu bestimmen. Wenn Sie mit besonders langen Zeichenfolgenwerten arbeiten, beachten Sie, dass die Eigenschaft properties über die Unicode-Skalare in der gesamten Zeichenfolge iterieren muss, um die Zeichen für diese Zeichenfolge zu ermitteln.

Die Anzahl der von der Eigenschaft properties zurückgegebenen Zeichen entspricht nicht immer der Eigenschaft length eines NSString, der dieselben Zeichen enthält. Die Länge eines NSStrings basiert auf der Anzahl der 16-Bit-Codeeinheiten in der UTF-16-Darstellung der Zeichenfolge und nicht auf der Anzahl der erweiterten Unicode-Graphemcluster in der Zeichenfolge.

Ein Beispiel, das die oben beschriebene Situation perfekt veranschaulicht, ist das Überprüfen der Länge einer Zeichenfolge, die ein einzelnes Emoji-Zeichen enthält, wie von n00neimp0rtant in den Kommentaren hervorgehoben.

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

26
Ich schätze Ihre ausführliche und warnende Antwort, aber ich muss zugeben, dass es mir unangenehm ist. Sie haben mir drei Möglichkeiten gegeben, um die Länge eines Strings zu ermitteln, alle mit dem Hinweis, dass die Antworten, die sie geben, möglicherweise nicht Ihren Erwartungen entsprechen. Gibt es wirklich keinen zuverlässigen Weg in Swift, um einen genauen, zuverlässigen Längenwert eines Strings zu erhalten?
n00neimp0rtant

6
@ n00neimp0rtant. Entschuldigung, wenn ich es nicht klar gemacht habe. Die erste Lösung ( countElements()) erhält die genaue Anzahl der Zeichen in der Zeichenfolge. Dies kann sich von dem unterscheiden, was Sie beim Aufrufen [str length]von Objective-C erhalten, da die lengthMethode davon ausgeht, dass alle Zeichen in der Zeichenfolge aus 16-Bit-Codeeinheiten bestehen, während countElements()die tatsächliche Anzahl der Unicode-Zeichen abgerufen wird. In den meisten Fällen liefern jedoch alle oben genannten Alternativen die gleichen Ergebnisse, insbesondere wenn Sie mit allgemeinen englischen Zeichen arbeiten.
Cezar

2
@ n00neimp0rtant Ich habe meine Antwort ein wenig optimiert, um sie klarer zu machen.
Cezar

2
Ich verstehe, was du jetzt meinst. Ich habe gerade versucht, die Länge einer Zeichenfolge zu ermitteln, die ein einzelnes Emoji-Zeichen enthält. Objective-C gab mir einen Wert von 4 und Swift gab mir einen Wert von 1. Es scheint also tatsächlich genauer zu sein (und daher ironischerweise "nicht das, was ich erwarten würde" = P). Danke für die Klarstellung!
n00neimp0rtant

1
@ n00neimp0rtant Genau! Das ist ein perfektes Beispiel. Ich werde es sogar zur Antwort hinzufügen
Cezar

92

Swift 1.2 Update: Es gibt keine countElements mehr zum Zählen der Größe von Sammlungen. Verwenden Sie einfach die Zählfunktion als Ersatz: count ("Swift")

Swift 2.0, 3.0 und 3.1:

let strLength = string.characters.count

Swift 4.2 (ab 4.0): [Apple Documentation - Strings]

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

Swift 4.2

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

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

6
Ja, wir brauchen eine Abstraktionsschicht für Swifts Syntax, die sich monatlich ändert!
Cosmin

@Lee Dies funktioniert in Swift 4 nicht, da Zeichen veraltet sind. Der herumlaufende Whac-a-Mole geht weiter. Seufzer
Eonist

48

Swift 4

"string".count

;)

Swift 3

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

Verwendungszweck

"string".length


Es gibt String.CharacterView.IndexDistance zurück. Was ist mit Int?
Eonist

@ GitSync wo? Ich verstehe dich nicht
Vyacheslav

@Vyacheslav in Swift 4 "String" .count gibt String.CharacterView.IndexDistance zurück. Siehe meine Antwort hier: stackoverflow.com/a/47203597/5389500 , um Int in Swift 3 und 4 zu erhalten
Eonist

Ich habe getestet, dass dies der Spielplatz ist:
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

Wenn Sie nur versuchen zu sehen, ob eine Zeichenfolge leer ist oder nicht (auf Länge 0 prüfen), bietet Swift eine einfache boolesche Testmethode an String

myString.isEmpty

Die andere Seite dieser Münze waren Leute, die in ObjectiveC fragten, wie man fragt, ob eine Zeichenfolge leer ist, wobei die Antwort darin bestand, nach einer Länge von 0 zu suchen:

NSString ist leer


18

tl; dr Wenn Sie die Länge eines String-Typs in Bezug auf die Anzahl der von Menschen lesbaren Zeichen angeben möchten , verwenden Sie countElements () . Wenn Sie die Länge in Bezug auf die Anzahl der erweiterten Graphemcluster wissen möchten , verwenden Sie endIndex . Lesen Sie weiter für Details.

Der String- Typ wird als geordnete Sammlung (dh Sequenz) von Unicode-Zeichen implementiert und entspricht dem CollectionType- Protokoll, das dem _CollectionType- Protokoll entspricht, dem von countElements () erwarteten Eingabetyp . Daher kann countElements () aufgerufen werden, indem ein String- Typ übergeben wird, und es wird die Anzahl der Zeichen zurückgegeben.

In Übereinstimmung mit CollectionType , das wiederum mit _CollectionType übereinstimmt , implementiert String jedoch auch die berechneten Eigenschaften startIndex und endIndex , die tatsächlich die Position des Index vor dem ersten Zeichencluster bzw. die Position des Index nach dem letzten Zeichencluster darstellen . In der Zeichenfolge "ABC" ist die Position des Index vor A 0 und nach C 3. Daher ist endIndex = 3, was auch die Länge der Zeichenfolge ist.

Also, endIndex kann verwendet werden , um die Länge eines String - Typs zu erhalten, dann, nicht wahr?

Nun, nicht immer ... Unicode-Zeichen sind tatsächlich erweiterte Graphemcluster , bei denen es sich um Sequenzen eines oder mehrerer Unicode-Skalare handelt, die zu einem einzigen für Menschen lesbaren Zeichen kombiniert werden.

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

circledStar ist ein einzelnes Zeichen, das aus U + 2606 (einem weißen Stern) und U + 20DD (einem kombinierenden umschließenden Kreis) besteht. Erstellen wir einen String aus circledStar und vergleichen Sie die Ergebnisse von countElements () und endIndex .

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

15

In Swift 2.0 countfunktioniert das nicht mehr. Sie können dies stattdessen verwenden:

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

14

Hier ist etwas kürzeres und natürlicheres als die Verwendung einer globalen Funktion:

aString.utf16count

Ich weiß allerdings nicht, ob es in Beta 1 verfügbar ist. Aber es ist definitiv in Beta 2 da.


2
Siehe Cezars Antwort. Dies gibt Ihnen nicht unbedingt die Anzahl der "Zeichen" in der Zeichenfolge, für die Definition von "Zeichen" durch die meisten Leute. Andererseits hat Objective-C es auch nicht getan - es liegt an Ihnen, zu entscheiden, ob Sie sich darum kümmern oder nicht.
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

Aktualisiert für Xcode 6 Beta 4, ändern Sie die Methode utf16count -> utf16Count

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

Oder

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

Wenn Sie komplexe Zeichenfolgen mit Emoji verwenden, ist die Antwort mit utf16countfalsch
Victor Sigler

10

Ab Swift 1.2 utf16Countwurde entfernt. Sie sollten jetzt die globale count()Funktion verwenden und die UTF16-Ansicht der Zeichenfolge übergeben. Beispiel unten ...

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

1
Ist es langsamer als .utf16count?
Samir105

1
Es scheint die gleiche Geschwindigkeit wie .utf16count, viel schneller als count (string)
samir105

8

Für Xcode 7.3 und Swift 2.2.

let str = "🐶"
  1. Wenn Sie die Anzahl der visuellen Zeichen möchten:

    str.characters.count
  2. Wenn Sie die "16-Bit-Codeeinheiten in der UTF-16-Darstellung der Zeichenfolge" möchten:

    str.utf16.count

Meistens ist 1 das, was Sie brauchen.

Wann würden Sie 2 brauchen ? Ich habe einen Anwendungsfall für 2 gefunden :

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

Wenn Sie 1 verwenden , ist das Ergebnis falsch:

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

7

Sie könnten es so versuchen

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

4
Das ist das gleiche wietest1.utf16count
Sulthan

1
@vladof gut, es "irgendwie" funktioniert. Siehe Cezars Antwort.
jbg

6

In Swift 2.x wird im Folgenden beschrieben, wie die Länge eines Strings ermittelt wird

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

gibt 24 zurück


5

Swift 2.0: Zählen Sie: yourString.text.characters.count

Ein lustiges Beispiel dafür, wie dies nützlich ist, wäre, einen Zeichen-Countdown von einer bestimmten Zahl (z. B. 150) in einer UITextView anzuzeigen:

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

4

In swift4 habe ich das string.countbis heute immer benutzt, das habe ich gefunden

string.endIndex.encodedOffset

ist die bessere Substitution, weil es schneller ist - für 50 000 Zeichen ist die Zeichenfolge ungefähr 6 Mal schneller als .count. Das .counthängt von der Stringlänge ab, .endIndex.encodedOffsettut es aber nicht.

Aber es gibt ein NEIN. Es ist nicht gut für Strings mit Emojis, es wird ein falsches Ergebnis liefern, also ist nur .countrichtig.


3

In Swift 4 : Wenn die Zeichenfolge keine Unicode-Zeichen enthält, verwenden Sie Folgendes

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

Wenn die Zeichenfolge Unicode-Zeichen enthält, verwenden Sie Folgendes:

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

Warum sollten Sie verwenden möchten utf8.count? Das gibt nicht die Anzahl der Zeichen. Es gibt die Anzahl der Bytes an, die für die UTF-8-Codierung der Zeichenfolge benötigt werden.
rmaddy

2

In Xcode 6.1.1

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

Ich denke, dass Brainiacs dies bei jeder Nebenversion ändern werden.


2

Rufen Sie den Zeichenfolgenwert aus Ihrer Textansicht oder Ihrem Textfeld ab:

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

Finden Sie die Anzahl der Zeichen in der Zeichenfolge:

let numberOfChars = textlength.characters.count

2

Hier ist, was ich letztendlich getan habe

let replacementTextAsDecimal = Double(string)

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

Ich denke, Sie versuchen mehr als nur die Länge der Zeichenfolge zu ermitteln, und dies sieht auf jeden Fall unvollständig aus (sollte es nicht auch einen return trueFall geben?). Können Sie bitte Ihre Antwort überprüfen und für den Fall bearbeiten ? Vielen Dank!
Fabio sagt Reinstate Monica

2

Swift 4 Update im Vergleich zu Swift 3

Swift 4 macht ein Zeichenarray für String überflüssig. Dies bedeutet, dass Sie counteine Zeichenfolge direkt aufrufen können, ohne zuerst ein Zeichenarray zu erhalten.

"hello".count                  // 5

Während in Swift 3 das Zeichenarray abgerufen und dann das Element in diesem Array gezählt werden muss. Beachten Sie, dass diese folgende Methode in Swift 4.0 weiterhin verfügbar ist, da Sie weiterhin aufrufen können, charactersum auf das Zeichenarray der angegebenen Zeichenfolge zuzugreifen

"hello".characters.count       // 5

Swift 4.0 übernimmt auch Unicode 9 und kann jetzt Graphemcluster interpretieren. Wenn Sie beispielsweise auf ein Emoji zählen, erhalten Sie 1, während Sie in Swift 3.0 möglicherweise mehr als 1 erhalten.

"👍🏽".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 

Denken Sie daran: Leerzeichen wird auch in der Zahl gezählt


2

Sie können die Länge einfach durch Schreiben einer Erweiterung ermitteln:

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)

Dies zählt die Zeichen in Regular Swift String

countElements((newString as String))    

Dies zählt die Zeichen in einem NSString


1

Der beste Weg, um String in Swift zu zählen, ist folgender:

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

2
Sie sollten nur count (str) verwenden. Versuchen Sie, count (str.utf16) mit Sub-String-Fortschritt () zu verwenden
Leo Dabus

1

String und NSString sind gebührenfreie Bridge, sodass Sie alle für NSString verfügbaren Methoden mit Swift String verwenden können

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

1
test1.characters.count

Sie erhalten die Anzahl der Buchstaben / Zahlen usw. in Ihrer Zeichenfolge.

Ex:

test1 = "StackOverflow"

print(test1.characters.count)

( druckt " 13 ")


1

Apple hat es anders gemacht als andere Hauptsprachen. Der aktuelle Weg ist anzurufen:

test1.characters.count

Um jedoch vorsichtig zu sein, wenn Sie Länge sagen, meinen Sie die Anzahl der Zeichen, nicht die Anzahl der Bytes, da diese beiden unterschiedlich sein können, wenn Sie Nicht-ASCII-Zeichen verwenden.

Zum Beispiel; "你好啊hi".characters.countgibt Ihnen 5, aber dies ist nicht die Anzahl der Bytes. Um die tatsächliche Anzahl der Bytes zu erhalten, müssen Sie dies tun "你好啊hi".lengthOfBytes(using: String.Encoding.utf8). Dies gibt Ihnen 11.


1

Im Moment (in Swift 2.3), wenn Sie Folgendes verwenden:

myString.characters.count 

Die Methode gibt den Typ "Distance" zurück. Wenn Sie die Methode benötigen, um eine Ganzzahl zurückzugeben, sollten Sie cast wie folgt eingeben:

var count = myString.characters.count as Int

2
Das Distancevon String.CharacterView ist Int , es sollte keine Notwendigkeit für diese Besetzung geben.
Martin R
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.