for array string swift

array - substring to string swift 3



La forma más rápida y sencilla de agregar caracteres para formar una cadena en Swift (1)

(Esta respuesta fue escrita en base a la documentación y el código fuente válido para Swift 2 y 3: posiblemente necesite actualizaciones y enmiendas una vez que llegue Swift 4)

Ya que Swift ahora es de código abierto, podemos ver el código fuente de la String nativa de Swift:

De la fuente anterior, hemos siguiente comentario

/// Growth and Capacity /// =================== /// /// When a string''s contiguous storage fills up, new storage must be /// allocated and characters must be moved to the new storage. /// `String` uses an exponential growth strategy that makes `append` a /// constant time operation *when amortized over many invocations*.

Teniendo en cuenta lo anterior, no debería preocuparse por el rendimiento de los caracteres agregados en Swift (ya sea a través de append(_: Character) , append(_: UniodeScalar) o appendContentsOf(_: String) ), como reasignación de los contiguos El almacenamiento para una determinada instancia de String no debe ser muy frecuente. Es necesario adjuntar el número de caracteres individuales para que se produzca esta reasignación.

También tenga en cuenta que NSMutableString no es Swift "puramente nativo", sino que pertenece a la familia de clases Obj-C puenteadas (a las que se puede acceder a través de Foundation ).

Una nota a tu comentario.

"Pensé que String era inmutable, pero noté que su método anexado devuelve Void ".

String es solo un tipo (valor), que puede ser usado por propiedades mutables e inmutables

var foo = "foo" // mutable let bar = "bar" // immutable /* (both the above inferred to be of type ''String'') */

Los métodos de instancia mutante void-return append(_: Character) y append(_: UniodeScalar) son accesibles a instancias de String mutables e inmutables, pero su uso con este último producirá un error de tiempo de compilación

let chars : [Character] = ["b","a","r"] foo.append(chars[0]) // "foob" bar.append(chars[0]) // error: cannot use mutating member on immutable value ...

Vengo de un fondo de C # donde System.String es inmutable y la concatenación de cadenas es relativamente costosa (ya que requiere la reasignación de la cadena). Sabemos que usamos el tipo StringBuilder lugar, ya que preasigna un búfer más grande donde caracteres individuales tipo de valor) y cadenas cortas se pueden concatenar a bajo costo sin asignación adicional.

Estoy transfiriendo algo de código C # a Swift, que se lee desde una matriz de bits ( [Bool] ) en índices de suboctetos con longitudes de caracteres menores a 8 bits (es un formato de archivo muy consciente del espacio).

Mi código C # hace algo como esto:

StringBuilder sb = new StringBuilder( expectedCharacterCount ); int idxInBits = 0; Boolean[] bits = ...; for(int i = 0; i < someLength; i++) { Char c = ReadNextCharacter( ref idxInBits, 6 ); // each character is 6 bits in this example sb.Append( c ); }

En Swift, asumo que NSMutableString es el equivalente de StringBuilder de .NET, y encontré este control de calidad sobre la adición de caracteres individuales ( ¿Cómo agregar un carácter a la cadena en Swift? ) Así que en Swift tengo esto:

var buffer: NSMutableString for i in 0..<charCount { let charValue: Character = readNextCharacter( ... ) buffer.AppendWithFormat("%c", charValue) } return String(buffer)

Pero no sé por qué pasa primero por una cadena de formato, eso parece ineficiente (volver a compartir la cadena de formato en cada iteración) y como mi código se ejecuta en dispositivos iOS, quiero ser muy conservador con la CPU y la memoria de mi programa uso.

Mientras escribía esto, aprendí que mi código realmente debería usar UnicodeScalar lugar de Character , el problema es que NSMutableString no te permite agregar un valor de UnicodeScalar , tienes que usar el propio tipo de String mutable de Swift, así que ahora mi código parece:

var buffer: String for i in 0..<charCount { let x: UnicodeScalar = readNextCharacter( ... ) buffer.append(x) } return buffer

Pensé que String era inmutable, pero noté que su método append devuelve Void .

Todavía me siento incómodo al hacer esto porque no sé cómo se implementa internamente el tipo String ''s String , y no veo cómo puedo preasignar un búfer grande para evitar reasignaciones (asumiendo que la String Swift utiliza un algoritmo creciente).