Como posso obter o enésimo caractere de uma string? Eu tentei o []
acessador bracket ( ) sem sorte.
var string = "Hello, world!"
var firstChar = string[0] // Throws error
ERRO: 'subscript' está indisponível: não é possível subscrever String com um Int, consulte o comentário da documentação para discussão
swift
string
collections
character
Mohsen
fonte
fonte
var firstChar = string.index(string.startIndex, offsetBy: 0)
vez dissostring.startIndex
? Para o primeiro personagemstring[string.startIndex]
ou simplesmentestring.first
. Note-se que a primeira abordagem, você precisa verificar se a cadeia está vazia pela primeira vez o segundo retorna um opcionalRespostas:
Atenção: Por favor, veja a resposta de Leo Dabus para uma implementação adequada do Swift 4 e Swift 5.
Swift 4 ou posterior
O
Substring
tipo foi introduzido no Swift 4 para tornar as substrings mais rápidas e mais eficientes, compartilhando o armazenamento com a string original, e é isso que as funções de subscrito devem retornar.Experimente aqui
Para converter o
Substring
em aString
, você pode simplesmente fazerString(string[0..2])
, mas só deve fazer isso se planejar manter a substring por perto. Caso contrário, é mais eficiente mantê-lo aSubstring
.Seria ótimo se alguém descobrisse uma boa maneira de mesclar essas duas extensões em uma. Eu tentei estenderNota: Esta resposta já foi editada, está implementada corretamente e agora também funciona para substrings. Apenas certifique-se de usar um intervalo válido para evitar falhas ao inscrever seu tipo StringProtocol. Para assinar com um intervalo que não trava com valores fora do intervalo, você pode usar esta implementaçãoStringProtocol
sem sucesso, porque oindex
método não existe lá.Por que isso não está embutido?
A mensagem de erro diz "consulte o comentário da documentação para discussão" . A Apple fornece a seguinte explicação no arquivo UnavailableStringAPIs.swift :
fonte
Cannot find an overload for 'advance' that accepts an argument list of type '(String.Index, T)'
...String.Index
eInt
não são compatíveis.Cannot subscript a value of type 'String'...
verifique esta resposta: stackoverflow.com/a/31265316/649379Ambiguous use of 'subscript'
.fatal error: Can't form a Character from an empty String
Swift 5.2
Você precisará adicionar esta extensão String ao seu projeto (ela foi totalmente testada):
Embora o Swift sempre tivesse uma solução pronta para esse problema (sem a extensão String, que forneci abaixo), eu ainda recomendaria fortemente o uso da extensão. Por quê? Porque isso me salvou dezenas de horas de migração dolorosa das versões anteriores do Swift, onde a sintaxe do String estava mudando em quase todos os lançamentos, mas tudo que eu precisava fazer era atualizar a implementação da extensão, em vez de refatorar todo o projeto. Faça a sua escolha.
fonte
range.upperBound - range.lowerBound
pararange.count
extension StringProtocol where Self: RangeReplaceableCollection { subscript(offset: Int) -> Element { get { return self[index(startIndex, offsetBy: offset)] } set { let start = index(startIndex, offsetBy: offset) replaceSubrange(start..<index(after: start), with: [newValue]) } } }
Eu só vim com essa solução legal
fonte
var firstChar = Array(string!)[0]
Caso contrário ele vai dizeradd arrayLiteral
Sem indexação usando números inteiros, apenas usando
String.Index
. Principalmente com complexidade linear. Você também pode criar intervalosString.Index
e obter substrings usando-os.Swift 3.0
Swift 2.x
Observe que você nunca pode usar um índice (ou intervalo) criado de uma sequência para outra
fonte
String
índices são exclusivos para uma string. Isso ocorre porque cadeias diferentes podem ter UTF-16 de várias unidades diferentesCharacters
e / ou em posições diferentes, para que os índices da unidade UTF-16 não correspondam, podem cair além do final ou ponto dentro de uma UTF-16 de várias unidadesCharacter
...
é agora..<
(na sua atribuição arange
)var lastChar = string[string.endIndex.predecessor()]
Xcode 11 • Swift 5.1
Você pode estender o StringProtocol para disponibilizar o subscrito também para as substrings:
Teste
fonte
return String(Array(characters)[range])
no Swift 3?Swift 4
String no índice
Substring
Primeiros n caracteres
Últimos n caracteres
Swift 2 e 3
** String no índice **
Swift 2
Swift 3
SubString deIndex paraIndex
Swift 2
Swift 3
Primeiros n caracteres
Últimos n caracteres
fonte
Swift 2.0 a partir da Xcode 7 GM Seed
Para o enésimo caractere, substitua 0 por n-1.
Edição: Swift 3.0
nb, existem maneiras mais simples de pegar certos caracteres na string
por exemplo
let firstChar = text.characters.first
fonte
Se você vir
Cannot subscript a value of type 'String'...
usar esta extensão:Swift 3
Swift 2.3
Fonte: http://oleb.net/blog/2014/07/swift-strings/
fonte
Solução Swift 2.2:
A extensão a seguir funciona no Xcode 7, é uma combinação dessa solução e da conversão de sintaxe do Swift 2.0.
fonte
A classe de cadeia rápida não fornece a capacidade de obter um caractere em um índice específico devido ao seu suporte nativo a caracteres UTF. O comprimento variável de um caractere UTF na memória torna impossível pular diretamente para um caractere. Isso significa que você deve repetir manualmente a seqüência de caracteres toda vez.
Você pode estender String para fornecer um método que percorrerá os caracteres até o índice desejado
fonte
myString.bridgeToObjectiveC().characterAtIndex(0)
ou(string as NSString ).characterAtIndex(0)
devolve um valor Int do personagemNSString
métodos para acessar caracteres individuais de um nativo do SwiftString
- os dois usam mecanismos de contagem diferentes, para obter resultados imprevisíveis com caracteres Unicode mais altos. O primeiro método deve ser seguro (uma vez que os erros Unicode do Swift sejam tratados).Como uma observação à parte, existem algumas funções aplicáveis diretamente à representação da cadeia de caracteres de uma String, assim:
O resultado é do tipo Caractere, mas você pode convertê-lo em uma String.
Ou isto:
:-)
fonte
Swift 4
Essa é provavelmente a melhor maneira de resolver esse problema uma vez. Você provavelmente deseja converter a String como uma matriz primeiro e depois converter o resultado como String novamente. Caso contrário, um caractere será retornado em vez de uma String.
O exemplo
String(Array("HelloThere")[1])
retornará "e" como uma String.(Array("HelloThere")[1]
retornará "e" como um personagem.O Swift não permite que as Strings sejam indexadas como matrizes, mas isso faz o trabalho, no estilo de força bruta.
fonte
Minha solução muito simples:
Swift 4.1:
Swift 5.1:
fonte
let flags = "🇺🇸🇧🇷"
flags[String.Index(utf16Offset: 4, in: flags)] // "🇧🇷"
Você pode fazer isso convertendo String em Array e obtendo-o por índice específico usando subscrito como abaixo
fonte
Eu apenas tive o mesmo problema. Simplesmente faça o seguinte:
fonte
NSString
.Swift3
Você pode usar a sintaxe do subscrito para acessar o Caractere em um índice String específico.
Visite https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html
ou podemos fazer uma extensão de string no Swift 4
USO:
fonte
Minha solução está em uma linha, supondo que cadena seja a string e 4 seja a enésima posição que você deseja:
Simples ... Suponho que o Swift inclua mais coisas sobre substrings em versões futuras.
fonte
var charAtIndex = string[advance(string.startIndex, 10)]
na resposta de Sulthan?Swift 3: outra solução (testada em playground)
Uso:
fonte
Atualização para substring 2.0 swift
fonte
Eu acho que uma resposta rápida para obter o primeiro personagem pode ser:
É muito elegante e com desempenho que:
Mas .. se você quiser manipular e executar mais operações com strings, você poderá criar uma extensão .. existe uma extensão com essa abordagem, é bem parecida com a já postada aqui:
}
MAS É UMA IDEIA TERRÍVEL !!
A extensão abaixo é terrivelmente ineficiente. Toda vez que uma string é acessada com um número inteiro, uma função O (n) para avançar seu índice inicial é executada. A execução de um loop linear dentro de outro loop linear significa que esse loop for é acidentalmente O (n2) - à medida que o comprimento da string aumenta, o tempo que esse loop leva aumenta quadraticamente.
Em vez de fazer isso, você pode usar a coleção de cadeias de caracteres.
fonte
Swift 3
Uso
Dicas e truques úteis de programação (escritos por mim)
fonte
Obter e definir subscrito (String e substring) - Swift 4.2
Swift 4.2, Xcode 10
Baseei minha resposta na resposta de @alecarlson . A única grande diferença é que você pode obter um
Substring
ou umString
retorno (e, em alguns casos, um únicoCharacter
). Você também podeget
eset
o subscrito. Por fim, o meu é um pouco mais complicado e mais longo que a resposta de @alecarlson e, como tal, sugiro que você o coloque em um arquivo de origem.Extensão:
fonte
Swift 4.2
Essa resposta é ideal porque ela se estende
String
e todas as suasSubsequences
(Substring
) em uma extensãoUso
fonte
start
eend
) dostartIndex
. Você pode simplesmente compensar oend
índice usando o range.count e compensar ostart
índiceAté agora, o subscrito (_ :) está indisponível. Assim como não podemos fazer isso
com string.Nós precisamos fornecer "String.Index". Mas como podemos fornecer nosso próprio número de índice dessa maneira, em vez disso, podemos usar,
fonte
string[string.startIndex]
? BTW, o código não se comportaria / compilaria corretamente, pois você usava dois nomes de variáveis diferentes.Swift 4.2 ou posterior
Subscrição de intervalo e intervalo parcial usando
String
'sindices
propriedadeComo variação da resposta agradável do @LeoDabus , podemos adicionar uma extensão adicional
DefaultIndices
com o objetivo de nos permitir voltar àindices
propriedadeString
ao implementar os subscritos personalizados (porInt
intervalos especializados e intervalos parciais) para o último.Obrigado @LeoDabus por me indicar na direção de usar a
indices
propriedade como uma (outra) alternativa àString
inscrição!fonte
swiftenv
quando o faço, mas acho que será atualizado com o 4.2 também em breve.Swift 5.1.3:
Adicione uma extensão String:
fonte
O
String
tipo de Swift não fornece umcharacterAtIndex
método porque existem várias maneiras de codificar uma string Unicode. Você vai com UTF8, UTF16 ou algo mais?Você pode acessar as
CodeUnit
coleções recuperando as propriedadesString.utf8
eString.utf16
. Você também pode acessar aUnicodeScalar
coleção recuperando oString.unicodeScalars
propriedade.No espírito da
NSString
implementação, estou retornando umunichar
tipo.fonte
Para alimentar o assunto e mostrar possibilidades rápidas de subscrito, aqui está uma pequena string "substring-toolbox" baseada em subscrito
Esses métodos são seguros e nunca passam por índices de string
fonte
Uma solução semelhante a python, que permite usar índice negativo,
poderia ser:
A propósito, pode valer a pena transpor toda a notação de fatia do python
fonte
Você também pode converter String em Array of Characters assim:
Esta é a maneira de obter char no índice especificado em tempo constante.
O exemplo abaixo não é executado em tempo constante, mas requer tempo linear. Portanto, se você tem muita pesquisa em String por índice, use o método acima.
fonte