¿Cómo puedo obtener el enésimo carácter de una cadena? Probé el []
accesorio de soporte ( ) sin suerte.
var string = "Hello, world!"
var firstChar = string[0] // Throws error
ERROR: 'subíndice' no está disponible: no puede subíndice Cadena con un Int, vea el comentario de la documentación para su discusión
swift
string
collections
character
Mohsen
fuente
fuente
var firstChar = string.index(string.startIndex, offsetBy: 0)
en su lugarstring.startIndex
? Para el primer personajestring[string.startIndex]
o simplementestring.first
. Tenga en cuenta que el primer enfoque que necesitaría para verificar si la cadena está vacía primero, el segundo devuelve un opcionalRespuestas:
Atención: consulte la respuesta de Leo Dabus para una implementación adecuada de Swift 4 y Swift 5.
Swift 4 o posterior
los
Substring
tipo se introdujo en Swift 4 para hacer que las subcadenas sean más rápidas y más eficientes al compartir el almacenamiento con la cadena original, por lo que las funciones de subíndice deberían volver.Pruébalo aquí
Para convertirlo
Substring
en aString
, simplemente puede hacerloString(string[0..2])
, pero solo debe hacerlo si planea mantener la subcadena alrededor. De lo contrario, es más eficiente mantenerlo aSubstring
.Sería genial si alguien pudiera encontrar una buena manera de combinar estas dos extensiones en una sola. Intenté extenderNota: Esta respuesta ya se ha editado, está implementada correctamente y ahora también funciona para las subcadenas. Solo asegúrese de usar un rango válido para evitar bloqueos al suscribir su tipo StringProtocol. Para suscribirse a un rango que no se bloqueará con valores fuera de rango, puede usar esta implementaciónStringProtocol
sin éxito, porque elindex
método no existe allí.¿Por qué esto no está incorporado?
El mensaje de error dice "ver el comentario de la documentación para la discusión" . Apple proporciona la siguiente explicación en el archivo UnavailableStringAPIs.swift :
fuente
Cannot find an overload for 'advance' that accepts an argument list of type '(String.Index, T)'
...String.Index
yInt
no son compatibles.Cannot subscript a value of type 'String'...
verifique esta respuesta: stackoverflow.com/a/31265316/649379Ambiguous use of 'subscript'
.fatal error: Can't form a Character from an empty String
Swift 5.2
Deberá agregar esta extensión de cadena a su proyecto (está completamente probado):
Aunque Swift siempre tuvo una solución inmediata a este problema (sin la extensión String, que proporcioné a continuación), todavía recomendaría encarecidamente usar la extensión. ¿Por qué? Debido a que me ahorró decenas de horas de migración dolorosa de las primeras versiones de Swift, donde la sintaxis de String estaba cambiando en casi todas las versiones, pero todo lo que tenía que hacer era actualizar la implementación de la extensión en lugar de refactorizar todo el proyecto. Haz tu elección.
fuente
range.upperBound - range.lowerBound
arange.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]) } } }
Se me ocurrió esta solución clara.
fuente
var firstChar = Array(string!)[0]
De lo contrario, diráadd arrayLiteral
Sin indexación con enteros, solo con
String.Index
. Principalmente con complejidad lineal. También puede crear rangos desdeString.Index
y obtener subcadenas con ellos.Swift 3.0
Swift 2.x
Tenga en cuenta que nunca puede usar un índice (o rango) creado de una cadena a otra cadena
fuente
String
Los índices son exclusivos de una cadena. Esto se debe a que diferentes cadenas pueden tener diferentes UTF-16 de múltiples unidadesCharacters
y / o en diferentes posiciones, por lo que los índices de la unidad UTF-16 no coincidirán, pueden caer más allá del final o punto dentro de un UTF-16 de múltiples unidadesCharacter
...
es ahora..<
(en su asignación arange
)var lastChar = string[string.endIndex.predecessor()]
Xcode 11 • Swift 5.1
Puede extender StringProtocol para que el subíndice esté disponible también para las subcadenas:
Pruebas
fuente
return String(Array(characters)[range])
en Swift 3?Swift 4
Cadena en el índice
Subcadena
Primero n caracteres
Últimos n caracteres
Swift 2 y 3
** Cadena en el índice **
Swift 2
Swift 3
Subcadena de índice a índice
Swift 2
Swift 3
Primero n caracteres
Últimos n caracteres
fuente
Swift 2.0 a partir de Xcode 7 GM Seed
Para el enésimo carácter, reemplace 0 con n-1.
Editar: Swift 3.0
nb hay formas más simples de agarrar ciertos caracteres en la cadena
p.ej
let firstChar = text.characters.first
fuente
Si ves
Cannot subscript a value of type 'String'...
usa esta extensión:Swift 3
Swift 2.3
Fuente: http://oleb.net/blog/2014/07/swift-strings/
fuente
Solución Swift 2.2:
La siguiente extensión funciona en Xcode 7, esta es una combinación de esta solución y la conversión de sintaxis Swift 2.0.
fuente
La clase de cadena rápida no proporciona la capacidad de obtener un carácter en un índice específico debido a su soporte nativo para caracteres UTF. La longitud variable de un personaje UTF en la memoria hace que sea imposible saltar directamente a un personaje. Eso significa que tienes que recorrer manualmente la cadena cada vez.
Puede extender String para proporcionar un método que recorra los caracteres hasta el índice deseado
fuente
myString.bridgeToObjectiveC().characterAtIndex(0)
o(string as NSString ).characterAtIndex(0)
devuelve un valor Int del personajeNSString
métodos para acceder a caracteres individuales de un nativo de SwiftString
: los dos usan mecanismos de conteo diferentes, por lo que obtendrá resultados impredecibles con caracteres Unicode más altos. El primer método debe ser seguro (una vez que se manejan los errores de Unicode de Swift).Como nota al margen, hay algunas funciones aplicables directamente a la representación de la cadena de caracteres de una cadena, como esta:
El resultado es de tipo Carácter, pero puede convertirlo en una Cadena.
O esto:
:-)
fuente
Swift 4
Esta es probablemente la mejor manera de resolver este problema una vez. Probablemente desee convertir el String como una matriz primero, y luego lanzar el resultado como un String nuevamente. De lo contrario, se devolverá un Carácter en lugar de una Cadena.
El ejemplo
String(Array("HelloThere")[1])
devolverá "e" como una cadena.(Array("HelloThere")[1]
devolverá "e" como un personaje.Swift no permite que las cadenas se indexen como matrices, pero esto hace el trabajo, estilo de fuerza bruta.
fuente
Mi solución muy simple:
Swift 4.1:
Swift 5.1:
fuente
let flags = "🇺🇸🇧🇷"
flags[String.Index(utf16Offset: 4, in: flags)] // "🇧🇷"
Puede hacerlo convirtiendo String en Array y obteniéndolo por índice específico usando el subíndice como se muestra a continuación
fuente
Acabo de tener el mismo problema. Simplemente haz esto:
fuente
NSString
.Swift3
Puede usar la sintaxis de subíndice para acceder al Carácter en un índice de Cadena particular.
Visite https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html
o podemos hacer una extensión de cadena en Swift 4
USO:
fuente
Mi solución está en una línea, suponiendo que cadena es la cadena y 4 es la enésima posición que desea:
Simple ... supongo que Swift incluirá más cosas sobre subcadenas en futuras versiones.
fuente
var charAtIndex = string[advance(string.startIndex, 10)]
en la respuesta de Sulthan?Swift 3: otra solución (probado en el patio de recreo)
Uso:
fuente
Actualización para swift 2.0 subString
fuente
Creo que una respuesta rápida para obtener el primer personaje podría ser:
Es mucho más elegante y de rendimiento que:
Pero ... si desea manipular y realizar más operaciones con cadenas, podría pensar crear una extensión ... hay una extensión con este enfoque, es bastante similar a la que ya se publicó aquí:
}
¡PERO ES UNA IDEA TERRIBLE!
La extensión a continuación es terriblemente ineficiente. Cada vez que se accede a una cadena con un número entero, se ejecuta una función O (n) para avanzar su índice de inicio. Ejecutar un bucle lineal dentro de otro bucle lineal significa que este bucle for accidentalmente es O (n2); a medida que aumenta la longitud de la cadena, el tiempo que tarda este bucle aumenta de forma cuadrática.
En lugar de hacerlo, puede usar la colección de cadenas de caracteres.
fuente
Swift 3
Uso
Consejos y trucos útiles de programación (escritos por mí)
fuente
Obtener y establecer subíndice (cadena y subcadena) - Swift 4.2
Swift 4.2, Xcode 10
Basé mi respuesta en la respuesta de @alecarlson . La única gran diferencia es que puede obtener una
Substring
o unaString
devolución (y en algunos casos, una solaCharacter
). También puedesget
yset
el subíndice. Por último, la mía es un poco más engorrosa y más larga que la respuesta de @alecarlson y, como tal, sugiero que la coloque en un archivo fuente.Extensión:
fuente
Swift 4.2
Esta respuesta es ideal porque se extiende
String
y todo suSubsequences
(Substring
) en una extensiónUso
fuente
start
yend
) delstartIndex
. Simplemente puede compensar elend
índice usando range.count y compensar elstart
índicePor ahora, el subíndice (_ :) no está disponible. Así como no podemos hacer esto
con cadena. Tenemos que proporcionar "String.Index" Pero, ¿cómo podemos dar nuestro propio número de índice de esta manera, en su lugar podemos usar,
fuente
string[string.startIndex]
? Por cierto, el código no se comportaría / compilaría correctamente, ya que usó dos nombres de variables diferentes.Swift 4.2 o posterior
Rango y suscripción parcial de rango usando
String
'sindices
propiedad deComo variación de la buena respuesta de @LeoDabus , podemos agregar una extensión adicional
DefaultIndices
con el fin de permitirnos recurrir a laindices
propiedad deString
cuando se implementan los subíndices personalizados (porInt
rangos especializados y rangos parciales) para este último.¡Gracias @LeoDabus por señalarme en la dirección de usar la
indices
propiedad como (otra) alternativa a laString
suscripción!fuente
swiftenv
embargo, lo uso cuando lo hago, supongo que se actualizará con 4.2 también un poco pronto.Swift 5.1.3:
Agregue una extensión de cadena:
fuente
El
String
tipo de Swift no proporciona uncharacterAtIndex
método porque hay varias formas de codificar una cadena Unicode. ¿Vas con UTF8, UTF16 u otra cosa?Puede acceder a las
CodeUnit
colecciones recuperando las propiedadesString.utf8
yString.utf16
. También puede acceder a laUnicodeScalar
colección recuperando laString.unicodeScalars
propiedad.En el espíritu de
NSString
implementación, estoy devolviendo ununichar
tipo.fuente
Para alimentar el tema y mostrar posibilidades rápidas de subíndice, aquí hay una pequeña cadena basada en el subíndice "substring-toolbox"
Estos métodos son seguros y nunca pasan por encima de los índices de cadena
fuente
Una solución similar a Python, que le permite usar índice negativo,
podría ser:
Por cierto, puede valer la pena transponer toda la notación de corte de la pitón
fuente
También puede convertir String a Array of Characters de esa manera:
Esta es la forma de obtener char en el índice especificado en tiempo constante.
El siguiente ejemplo no se ejecuta en tiempo constante, pero requiere tiempo lineal. Entonces, si tiene muchas búsquedas en String por índice, use el método anterior.
fuente