Obter o comprimento de uma String

781

Como você consegue o comprimento de um String? Por exemplo, eu tenho uma variável definida como:

var test1: String = "Scott"

No entanto, parece que não consigo encontrar um método de comprimento na string.

Scott Walter
fonte
possível duplicado do comprimento da corda em Swift 1.2 e 2.0 Swift
Rei-Assistente
Eu tive que migrar muito código manualmente por causa do Swift 3. Por isso, decidi criar extensões. Portanto, agora, se for necessário atualizar para uma nova versão principal, preciso migrar apenas a extensão. Aqui você encontra algumas extensões do Swift 3 que eu criei. github.com/tukur187/Swift3
Shkelzen

Respostas:

1284

A partir do Swift 4+

É apenas:

test1.count

por razões.

(Obrigado a Martin R)

A partir do Swift 2:

Com o Swift 2, a Apple mudou as funções globais para extensões de protocolo, extensões que correspondem a qualquer tipo em conformidade com um protocolo. Portanto, a nova sintaxe é:

test1.characters.count

(Obrigado a JohnDifool pelo aviso)

A partir do Swift 1

Use o método de contagem de caracteres:

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

direto do Guia Apple Swift

(observe, para versões do Swift anteriores à 1.2, isso seria o caso countElements(unusualMenagerie))

para sua variável, seria

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

Ou você pode usar test1.utf16count

mginn
fonte
11
Interessante que countElements é uma função global. Existe uma lista de funções globais?
Scott Walter
7
O problema com countElements é que ele é declarado assim: func countElements <T> (x: T) -> T.IndexType.DistanceType e o tipo de retorno não aceita a operação +.
MarkAurelius
288
Era muito difícil adicionar um método str.length. (levanta o punho com raiva)
botbot
13
Com Swift 2, só posso chegar a este trabalho: deixar len = test1.characters.count
Laurent
7
Observe que com o Swift 4, será string.count.
Martin R
335

TLDR:

Para Swift 2.0 e 3.0, use test1.characters.count. Mas, há algumas coisas que você deve saber. Então, continue a ler.

Contando caracteres no Swift

Antes do Swift 2.0, countera uma função global. A partir do Swift 2.0, ele pode ser chamado como uma função de membro.

test1.characters.count

Ele retornará o número real de caracteres Unicode em a String, portanto, é a alternativa mais correta no sentido de que, se você imprimir a string e contar caracteres à mão, obterá o mesmo resultado.

No entanto, devido à maneira como Stringssão implementadas no Swift, os caracteres nem sempre ocupam a mesma quantidade de memória; portanto, lembre-se de que isso se comporta de maneira bem diferente dos métodos comuns de contagem de caracteres em outros idiomas.

Por exemplo, você também pode usar test1.utf16.count

Mas, como observado abaixo, o valor retornado não é garantido para ser o mesmo que o de chamar counton characters.

A partir da referência do idioma:

Clusters de grafema estendidos podem ser compostos de um ou mais escalares Unicode. Isso significa que caracteres diferentes - e diferentes representações do mesmo caractere - podem exigir quantidades diferentes de memória para serem armazenadas. Por esse motivo, os caracteres no Swift não ocupam a mesma quantidade de memória na representação de uma string. Como resultado, o número de caracteres em uma sequência não pode ser calculado sem percorrer a sequência para determinar seus limites estendidos do cluster grafema. Se você estiver trabalhando com valores de cadeia particularmente longos, lembre-se de que a propriedade de caracteres deve iterar sobre os escalares Unicode em toda a cadeia, a fim de determinar os caracteres dessa cadeia.

A contagem dos caracteres retornados pela propriedade caracteres nem sempre é igual à propriedade length de um NSString que contém os mesmos caracteres. O comprimento de um NSString é baseado no número de unidades de código de 16 bits na representação UTF-16 da string e não no número de clusters de grafema estendidos Unicode na string.

Um exemplo que ilustra perfeitamente a situação descrita acima é o de verificar o comprimento de uma sequência que contém um único caractere emoji, conforme apontado por n00neimp0rtant nos comentários.

var emoji = "👍"
emoji.characters.count             //returns 1
emoji.utf16.count                  //returns 2
Cezar
fonte
26
Agradeço sua resposta detalhada e cautelosa, mas devo admitir que me deixou desconfortável. Você me deu três maneiras de obter o comprimento de uma string, todas com a isenção de responsabilidade de que as respostas que elas dão podem não ser o que você espera. Não existe realmente nenhuma maneira confiável incorporada ao Swift para obter um valor preciso e confiável do comprimento de uma string?
n00neimp0rtant
6
@ n00neimp0rtant. Desculpe se eu não deixei claro. A primeira solução ( countElements()) obtém o número exato de caracteres na String. Pode ser diferente do que você obteria ao chamar [str length]Objective-C, porque o lengthmétodo assume que todos os caracteres da sequência são compostos por unidades de código de 16 bits, enquanto countElements()obtém o número real de caracteres Unicode. No entanto, na maioria das vezes, todas as alternativas acima retornam os mesmos resultados, especialmente se você estiver trabalhando com caracteres comuns no idioma inglês.
Cezar
2
@ n00neimp0rtant Alterei um pouco minha resposta para tentar torná-la mais clara.
Cezar
2
Entendo o que você quer dizer agora. Eu apenas tentei obter o comprimento de uma string contendo um único caractere Emoji; O objetivo-C me deu um valor de 4, e Swift me deu um valor de 1. Portanto, parece realmente mais preciso (e, portanto, ironicamente "não é o que eu esperaria" = P). Obrigado pelo esclarecimento!
n00neimp0rtant
1
@ n00neimp0rtant Exatamente! Esse é um exemplo perfeito. Eu mesmo vou adicioná-lo à resposta
Cezar
92

Atualização Swift 1.2: não há mais countElements para contar o tamanho das coleções. Basta usar a função count como um substituto: count ("Swift")

Swift 2.0, 3.0 e 3.1:

deixe strLength = string.characters.count

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

deixe strLength = string.count

San
fonte
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)
Whitneyland
fonte
6
Sim, precisamos de uma camada de abstração para a sintaxe do Swift, que muda mensalmente!
Cosmin
@ Lee Isso não funciona no 4. rápido, pois os caracteres estão obsoletos. A correria por aí continua. sigh
eonist
48

Swift 4

"string".count

;)

Swift 3

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

uso

"string".length

Vyacheslav
fonte
Retorna String.CharacterView.IndexDistance. E o Int?
eonist
@GitSync onde? Eu não te entendo #
21917 Vyacheslav
@Vyacheslav em rápida 4 "string" retornos .Count String.CharacterView.IndexDistance Veja minha resposta aqui: stackoverflow.com/a/47203597/5389500 para obter int em Swift 3 e 4
eonist
Eu testei este é o parque infantil:
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 você está apenas tentando ver se uma string está vazia ou não (verificando se o comprimento é 0), o Swift oferece um método de teste booleano simples em String

myString.isEmpty

O outro lado dessa moeda eram pessoas perguntando no ObjectiveC como perguntar se uma string estava vazia, onde a resposta era verificar se o comprimento era 0:

NSString está vazio

Kendall Helmstetter Gelner
fonte
18

tl; dr Se você deseja o comprimento de um tipo String em termos do número de caracteres legíveis por humanos, use countElements () . Se você quiser saber o tamanho em termos do número de clusters de grafema estendidos , use endIndex . Continue lendo para obter detalhes.

O tipo String é implementado como uma coleção ordenada (ou seja, sequência) de caracteres Unicode e está em conformidade com o protocolo CollectionType , que está em conformidade com o protocolo _CollectionType , que é o tipo de entrada esperado por countElements () . Portanto, countElements () pode ser chamado, passando um tipo String e retornará a contagem de caracteres.

No entanto, em conformidade com CollectionType , que por sua vez está em conformidade com _CollectionType , Cordas também implementa as startIndex e endIndex propriedades computadas, o que realmente representam a posição do índice antes de o primeiro conjunto de caracteres, ea posição do índice após o último cluster caráter, respectivamente . Portanto, na cadeia "ABC", a posição do índice antes de A é 0 e depois de C é 3. Portanto, endIndex = 3, que também é o comprimento da cadeia.

Então, endIndex pode ser usado para obter o comprimento de qualquer tipo de String, certo?

Bem, nem sempre ... Os caracteres Unicode são, na verdade , conjuntos de grafemas estendidos , que são sequências de um ou mais escalares Unicode combinados para criar um único caractere legível por humanos.

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

circledStar é um caractere único composto por U + 2606 (uma estrela branca) e U + 20DD (um círculo anexo). Vamos criar uma String a partir de circledStar e comparar os resultados de countElements () e endIndex .

let circledStarString = "\(circledStar)"
countElements(circledStarString) // 1
circledStarString.endIndex // 2
Scott Gardner
fonte
15

No Swift 2.0 countnão funciona mais. Você pode usar isso:

var testString = "Scott"
var length = testString.characters.count
Antoine
fonte
14

Aqui está algo mais curto e mais natural do que usar uma função global:

aString.utf16count

Não sei se está disponível na versão beta 1. Mas está definitivamente lá na versão beta 2.

Jean Le Moignan
fonte
2
Veja a resposta de Cezar. Isso não fornecerá necessariamente o número de "caracteres" na string, para a definição de "caractere" da maioria das pessoas. Por outro lado, nem o Objective-C - cabe a você decidir se você se importa ou não.
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"
Saranjith
fonte
11

Atualizado para o Xcode 6 beta 4, altere o método utf16count -> utf16Count

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

Ou

 var test1: String = "Scott"
 var length = test1.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)
Kiet Nguyen
fonte
Quando você estiver usando cordas complexas com emoji, a resposta com utf16countserá errado
Victor Sigler
10

A partir do Swift 1.2 utf16Countfoi removida. Agora você deve usar a count()função global e passar a visualização UTF16 da string. Exemplo abaixo ...

let string = "Some string"
count(string.utf16)
Jeremy Fox
fonte
1
É mais lento que .utf16count?
samir105
1
Parece a mesma velocidade que .utf16count, muito mais rápido do que a contagem (string)
samir105
8

Para o Xcode 7.3 e Swift 2.2.

let str = "🐶"
  1. Se você deseja o número de caracteres visuais:

    str.characters.count
  2. Se você deseja "as unidades de código de 16 bits na representação UTF-16 da string":

    str.utf16.count

Na maioria das vezes, 1 é o que você precisa.

Quando você precisaria de 2 ? Encontrei um caso de uso para 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 você usar 1 , o resultado está incorreto:

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

Você poderia tentar assim

var test1: String = "Scott"
var length =  test1.bridgeToObjectiveC().length
Anil Varghese
fonte
4
É o mesmo quetest1.utf16count
Sulthan 4/14
1
@ Vladlad bem, "meio que" funciona. Veja a resposta de Cezar.
jbg
6

no Swift 2.x, a seguir, é como encontrar o comprimento de uma string

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

retorna 24

Adão
fonte
5

Swift 2.0: obtenha uma contagem: yourString.text.characters.count

Um exemplo divertido de como isso é útil seria mostrar uma contagem regressiva de caracteres de algum número (150 por exemplo) em um UITextView:

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

No swift4 eu sempre usei string.countaté hoje, descobri que

string.endIndex.encodedOffset

é a melhor substituição porque é mais rápida - para 50 000 caracteres, a sequência é cerca de 6 vezes mais rápida que .count. O .countdepende do comprimento da corda, mas .endIndex.encodedOffsetnão o faz.

Mas existe um NÃO. Não é bom para seqüências de caracteres com emojis, ele dará resultado errado, portanto, apenas .countestá correto.

VYT
fonte
3

No Swift 4 : se a sequência não contiver caracteres unicode, use o seguinte

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

Se a sequência contiver caracteres unicode, use o seguinte:

let spain = "España"
let count1 = spain.count // output 6
let count2 = spain.utf8.count // output 7
Ashis Laha
fonte
Por que você gostaria de usar utf8.count? Isso não dá a contagem de caracteres. Ele fornece o número de bytes necessários para a codificação UTF-8 da sequência.
rmaddy
2

No Xcode 6.1.1

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

Eu acho que os brainiacs vão mudar isso em todas as versões menores.

user3812138
fonte
2

Obtenha o valor da sequência de caracteres na sua visualização de texto ou campo de texto:

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

Encontre a contagem dos caracteres na string:

let numberOfChars = textlength.characters.count
kalyan711987
fonte
2

Aqui está o que eu acabei fazendo

let replacementTextAsDecimal = Double(string)

if string.characters.count > 0 &&
    replacementTextAsDecimal == nil &&
    replacementTextHasDecimalSeparator == nil {
        return false
}
Bryan Clark
fonte
Eu acho que você está tentando fazer mais do que apenas obter o comprimento da string e, de qualquer forma, isso parece incompleto (não deveria haver um return truecaso também?). Você pode verificar e, no caso, editar sua resposta? Obrigado!
Fabio diz Reinstate Monica
2

Atualização do Swift 4 em comparação com o Swift 3

O Swift 4 remove a necessidade de uma matriz de caracteres na String. Isso significa que você pode chamar diretamente countuma sequência sem obter primeiro a matriz de caracteres.

"hello".count                  // 5

Enquanto no swift 3, você precisará obter uma matriz de caracteres e depois contar o elemento nessa matriz. Observe que este método a seguir ainda está disponível no swift 4.0, pois você ainda pode chamar characterspara acessar a matriz de caracteres da sequência especificada

"hello".characters.count       // 5

O Swift 4.0 também adota o Unicode 9 e agora pode interpretar clusters de grafema. Por exemplo, contar com um emoji lhe dará 1 enquanto no swift 3.0, você pode obter contagens maiores que 1.

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

Swift 4

let str =  "Your name"

str.count 

Lembre-se: o espaço também é contado no número

Mr.Shin
fonte
2

Você pode obter o comprimento simplesmente escrevendo uma extensão:

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
    }
}
Riajur Rahman
fonte
1
var str = "Hello, playground"
var newString = str as NSString    

countElements(str)

Isso conta os caracteres em Regular Swift String

countElements((newString as String))    

Isso conta os caracteres em um NSString

brokenrhino
fonte
1

A melhor maneira de contar String em Swift é esta:

var str = "Hello World"
var length = count(str.utf16)
Zaldy
fonte
2
Você deve usar apenas count (str). Tente contagem de uso tu (str.utf16) com sub string de antecedência ()
Leo Dabus
1

String e NSString são pontes gratuitas para que você possa usar todos os métodos disponíveis para o NSString com String rápida

let x = "test" as NSString
let y : NSString = "string 2"
let lenx = x.count
let leny = y.count
Tien Dinh
fonte
1
test1.characters.count

você receberá o número de letras / números etc em sua string.

ex:

test1 = "StackOverflow"

print(test1.characters.count)

( imprime " 13 ")

Andy Lebowitz
fonte
1

A Apple tornou diferente de outro idioma importante. A maneira atual é chamar:

test1.characters.count

No entanto, para ter cuidado, quando você diz comprimento, significa a contagem de caracteres e não a contagem de bytes, porque esses dois podem ser diferentes quando você usa caracteres não-ascii.

Por exemplo; "你好啊hi".characters.countlhe dará 5, mas essa não é a contagem de bytes. Para obter a contagem real de bytes, você precisa "你好啊hi".lengthOfBytes(using: String.Encoding.utf8). Isso lhe dará 11.

Frank
fonte
1

Agora (no Swift 2.3) se você usar:

myString.characters.count 

o método retornará um tipo "Distância", se você precisar retornar um número inteiro, digite cast da seguinte forma:

var count = myString.characters.count as Int
Jesse
fonte
2
O Distancede String.CharacterView é Int , não deve haver necessidade para este elenco.
Martin R