Todos los siguientes ejemplos usan
var str = "Hello, playground"
Swift 4
Las cadenas obtuvieron una revisión bastante grande en Swift 4. Cuando obtienes una subcadena de una cadena ahora, obtienes un Substring
tipo de regreso en lugar de unString
. ¿Por qué es esto? Las cadenas son tipos de valor en Swift. Eso significa que si usa una Cadena para hacer una nueva, entonces debe copiarse. Esto es bueno para la estabilidad (nadie más lo va a cambiar sin su conocimiento) pero malo para la eficiencia.
Una subcadena, por otro lado, es una referencia a la cadena original de la que proviene. Aquí hay una imagen de la documentación que ilustra eso.
No se necesita copiar, por lo que es mucho más eficiente de usar. Sin embargo, imagina que tienes una subcadena de diez caracteres de una cadena de un millón de caracteres. Debido a que la Subcadena hace referencia a la Cadena, el sistema tendría que retener la Cadena completa mientras la Subcadena esté alrededor. Por lo tanto, cada vez que termine de manipular su Subcadena, conviértala en una Cadena.
let myString = String(mySubstring)
Esto copiará solo la subcadena y la memoria que contiene la antigua cadena puede recuperarse . Las subcadenas (como tipo) están destinadas a ser de corta duración.
Otra gran mejora en Swift 4 es que las cadenas son colecciones (nuevamente). Eso significa que cualquier cosa que pueda hacer a una Colección, puede hacerlo a una Cadena (usar subíndices, iterar sobre los caracteres, filtrar, etc.).
Los siguientes ejemplos muestran cómo obtener una subcadena en Swift.
Obteniendo subcadenas
Usted puede obtener una subcadena de una cadena mediante el uso de subíndices o una serie de otros métodos (por ejemplo, prefix
, suffix
, split
). Sin embargo, aún necesita usar String.Index
y no un Int
índice para el rango. (Ver mi otra respuesta si necesita ayuda con eso).
Comienzo de una cuerda
Puede usar un subíndice (tenga en cuenta el rango unilateral Swift 4):
let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str[..<index] // Hello
o prefix
:
let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str.prefix(upTo: index) // Hello
o incluso más fácil:
let mySubstring = str.prefix(5) // Hello
Fin de una cuerda.
Usando subíndices:
let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str[index...] // playground
o suffix
:
let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str.suffix(from: index) // playground
o incluso más fácil:
let mySubstring = str.suffix(10) // playground
Tenga en cuenta que al usar el suffix(from: index)
tuve que contar desde el final usando -10
. Eso no es necesario cuando solo se usa suffix(x)
, que solo toma los últimos x
caracteres de una Cadena.
Rango en una cuerda
Nuevamente, simplemente usamos subíndices aquí.
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end
let mySubstring = str[range] // play
Convertir Substring
aString
No olvide que, cuando esté listo para guardar su subcadena, debe convertirla en a String
para que se pueda limpiar la memoria de la cadena anterior.
let myString = String(mySubstring)
¿Usando una Int
extensión de índice?
Dudo en usar una Int
extensión de índice basada después de leer el artículo Strings in Swift 3 de Airspeed Velocity y Ole Begemann. Aunque en Swift 4, las cadenas son colecciones, el equipo de Swift no ha utilizado Int
índices a propósito . Está quieto String.Index
. Esto tiene que ver con que los caracteres Swift están compuestos por un número variable de puntos de código Unicode. El índice real tiene que calcularse de manera única para cada cadena.
Tengo que decir que espero que el equipo de Swift encuentre una forma de abstraerse String.Index
en el futuro. Pero hasta ellos elijo usar su API. Me ayuda a recordar que las manipulaciones de cadenas no son simples Int
búsquedas de índice.