Es hora de admitir la derrota ...
En Objective-C, podría usar algo como:
NSString* str = @"abcdefghi";
[str rangeOfString:@"c"].location; // 2
En Swift, veo algo similar:
var str = "abcdefghi"
str.rangeOfString("c").startIndex
... pero eso solo me da un String.Index
, que puedo usar para volver a subíndice en la cadena original, pero no extraer una ubicación de.
FWIW, que String.Index
tiene un ivar privado llamado _position
que tiene el valor correcto. Simplemente no veo cómo está expuesto.
Sé que podría agregar esto fácilmente a String. Tengo más curiosidad sobre lo que me falta en esta nueva API.
Respuestas:
No eres el único que no pudo encontrar la solución.
String
no implementaRandomAccessIndexType
. Probablemente porque habilitan caracteres con diferentes longitudes de bytes. Es por eso que tenemos que usarstring.characters.count
(count
ocountElements
en Swift 1.x) para obtener el número de caracteres. Eso también se aplica a los puestos. El_position
es probablemente un índice en la matriz de bytes en bruto y que no quieren exponer a eso. ElString.Index
objetivo es protegernos del acceso a bytes en medio de los caracteres.Eso significa que cualquier índice que obtenga debe crearse desde
String.startIndex
oString.endIndex
(String.Index
implementaBidirectionalIndexType
). Cualquier otro índice se puede crear usandosuccessor
opredecessor
métodos.Ahora, para ayudarnos con los índices, hay un conjunto de métodos (funciones en Swift 1.x):
Swift 4.x
Swift 3.0
Swift 2.x
Swift 1.x
Trabajar con
String.Index
es engorroso, pero usar un contenedor para indexar por enteros (ver https://stackoverflow.com/a/25152652/669586 ) es peligroso porque oculta la ineficiencia de la indexación real.Tenga en cuenta que la implementación de indexación Swift tiene el problema de que los índices / rangos creados para una cadena no pueden usarse de manera confiable para una cadena diferente , por ejemplo:
Swift 2.x
Swift 1.x
fuente
range
envar range = text.rangeOfString("b")
Collection
tiene untypealias IndexType
. Para las matrices, se define comoInt
, porqueString
se define comoString.Index
. Tanto las matrices como las cadenas también pueden usar rangos (para crear submatrices y subcadenas). La gama es un tipo especialRange<T>
. Para cadenas, esRange<String.Index>
, para matricesRange<Int>
.Swift 2.0
, sedistance(text.startIndex, range.startIndex)
conviertetext.startIndex.distanceTo(range.startIndex)
String
, exactamente comoNSString
en Foundation tiene un método llamadohasPrefix(_:)
.Swift 3.0 hace esto un poco más detallado:
Extensión:
En Swift 2.0 esto se ha vuelto más fácil:
Extensión:
Implementación Swift 1.x:
Para una solución Swift pura se puede usar:
Como una extensión para
String
:fuente
fuente
He encontrado esta solución para swift2:
fuente
Swift 5.0
Swift 4.0
fuente
No estoy seguro de cómo extraer la posición de String.Index, pero si está dispuesto a recurrir a algunos marcos de Objective-C, puede hacer un puente hacia el objetivo-c y hacerlo de la misma manera que solía hacerlo.
Parece que algunos métodos de NSString aún no han sido (o tal vez no serán) portados a String. Contiene también viene a la mente.
fuente
bridgeToObjectiveC()
llamada no es necesaria. Mi problema parece manifestarse solo cuando llamorangeOfString
a Swift String previamente existente. Parece un problema de API ...Aquí hay una extensión de cadena limpia que responde a la pregunta:
Swift 3:
Swift 2.2:
fuente
También puede encontrar índices de un carácter en una sola cadena como esta,
Lo que da el resultado en [String.Distance] es decir. [Int], como
fuente
Si desea utilizar NSString familiar, puede declararlo explícitamente:
Todavía no estoy seguro de cómo hacer esto en Swift.
fuente
Si desea conocer la posición de un carácter en una cadena como valor int , use esto:
fuente
value of type 'Range<String.Index>?' has no member 'location'
.Sé que esto es antiguo y se ha aceptado una respuesta, pero puede encontrar el índice de la cadena en un par de líneas de código usando:
Alguna otra gran información sobre las cadenas Swift aquí Cuerdas en Swift
fuente
find
no está disponible en Swift 3Esto funcionó para mí
esto funcionó también,
fuente
var str = "abcdef"; str.rangeOfString("c").location
genera un error sobre String.Index que no tiene un miembro llamado ubicación ...La cadena de tipo variable en Swift contiene diferentes funciones en comparación con NSString en Objective-C. Y como mencionó Sulthan,
Lo que puede hacer es bajar su variable de tipo String a NSString (esto es válido en Swift). Esto le dará acceso a las funciones en NSString.
fuente
Si lo piensa, en realidad no necesita la versión Int exacta de la ubicación. El rango o incluso el String.Index es suficiente para volver a sacar la subcadena si es necesario:
fuente
La forma más simple es:
En Swift 3 :
fuente
La cadena es un tipo de puente para NSString, así que agregue
a su archivo rápido y use todos los métodos "antiguos".
fuente
En términos de pensamiento, esto podría llamarse una INVERSIÓN. Descubres que el mundo es redondo en lugar de plano. "Realmente no necesitas saber el ÍNDICE del personaje para hacer cosas con él". Y como programador en C, ¡también me resultó difícil hacerlo! Su línea "let index = letters.characters.indexOf (" c ")!" Es suficiente por sí mismo. Por ejemplo, para eliminar la c que podría usar ... (pegar en el patio de recreo)
Sin embargo, si desea un índice, debe devolver un ÍNDICE real, no un Int, ya que un valor Int requeriría pasos adicionales para cualquier uso práctico. Estas extensiones devuelven un índice, un recuento de un personaje específico y un rango que demostrará este código enchufable para juegos.
fuente
Solución completa Swift 4:
OffsetIndexableCollection (String usando Int Index)
https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-
fuente
cadena de extensión {
}
fuente
Swift 5
Encontrar índice de subcadena
Encontrar índice de personaje
fuente
Si está buscando una manera fácil de obtener el índice de caracteres o cadenas, consulte esta biblioteca http://www.dollarswift.org/#indexof-char-character-int
Puede obtener el indexOf de una cadena usando otra cadena también o un patrón regex
fuente
Para obtener el índice de una subcadena en una cadena con Swift 2:
fuente
En swift 2.0
fuente
fuente
Juego con seguir
hasta que entiendo el proporcionado ahora es solo matriz de caracteres
y con
fuente
Si solo necesita el índice de un personaje, la solución más simple y rápida (como ya lo señaló Pascal) es:
fuente
Sobre el tema de convertir un
String.Index
en unInt
, esta extensión funciona para mí:Ejemplo de uso relevante a esta pregunta:
Importante:
Como puede ver, agrupa grupos de grafemas extendidos y caracteres unidos de manera diferente
String.Index
. Por supuesto, es por eso que tenemosString.Index
. Debe tener en cuenta que este método considera que los clústeres son caracteres singulares, lo que está más cerca de corregir. Si su objetivo es dividir una cadena por un punto de código Unicode, esta no es la solución para usted.fuente
En Swift 2.0 , la siguiente función devuelve una subcadena antes de un carácter dado.
fuente
Puede encontrar el número de índice de un carácter en una cadena con esto:
fuente
Como mi perspectiva, la mejor manera de conocer la lógica en sí está por debajo
fuente