Saltar al contenido

Obtener el enésimo carácter de un string en el lenguaje de programación Swift

Al fin después de mucho trabajar ya hallamos el arreglo de este rompecabezas que algunos los usuarios de nuestra web han tenido. Si tienes algo más que aportar no dudes en dejar tu comentario.

Solución:

Atención: Consulte la respuesta de Leo Dabus para una implementación adecuada para Swift 4 y Swift 5.

Swift 4 o posterior

los Substring type se introdujo en Swift 4 para hacer que las subcadenas sean más rápidas y eficientes al compartir el almacenamiento con el original string, así que eso es lo que deberían devolver las funciones de subíndice.

Pruébalo aquí

extension StringProtocol 
    subscript(offset: Int) -> Character  self[index(startIndex, offsetBy: offset)] 
    subscript(range: Range) -> SubSequence 
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..) -> SubSequence 
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..) -> SubSequence  self[index(startIndex, offsetBy: range.lowerBound)...] 
    subscript(range: PartialRangeThrough) -> SubSequence  self[...index(startIndex, offsetBy: range.upperBound)] 
    subscript(range: PartialRangeUpTo) -> SubSequence  self[..

Para convertir el Substring en un String, simplemente puedes hacer String(string[0..2]), pero solo debe hacerlo si planea mantener la subcadena. De lo contrario, es más eficiente mantenerlo Substring.

Sería genial si alguien pudiera encontrar una buena manera de fusionar estas dos extensiones en una. Intenté extender StringProtocol
sin éxito, porque el index El método no existe allí.
Nota: Esta respuesta ya ha sido editada, está implementada correctamente y ahora también funciona para subcadenas. Solo asegúrese de usar un rango válido para evitar fallas al subíndice su tipo StringProtocol. Para subíndices con un rango que no se bloqueará con valores fuera del rango, puede usar esta implementación


¿Por qué no está integrado?

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:

Las cadenas de subíndice con números enteros no están disponibles.

El concepto de "la ith personaje en un string"tiene diferentes interpretaciones en diferentes bibliotecas y componentes del sistema. La interpretación correcta debe seleccionarse de acuerdo con el caso de uso y las API involucradas, por lo que String
no se puede incluir en un subíndice con un número entero.

Swift proporciona varias formas diferentes de acceder a los datos de caracteres almacenados dentro de las cadenas.

  • String.utf8 es una colección de unidades de código UTF-8 en el
    string. Utilice esta API al convertir el string a UTF-8. La mayoría de las API de POSIX procesan cadenas en términos de unidades de código UTF-8.

  • String.utf16 es una colección de unidades de código UTF-16 en
    string. La mayoría de las API de Cocoa y Cocoa touch procesan cadenas en términos de unidades de código UTF-16. Por ejemplo, instancias de
    NSRange usado con NSAttributedString y
    NSRegularExpression almacenar las compensaciones y longitudes de las subcadenas en términos de unidades de código UTF-16.

  • String.unicodeScalars es una colección de escalares Unicode. Utilice esta API cuando esté realizando una manipulación de bajo nivel de datos de caracteres.

  • String.characters es una colección de grupos de grafemas extendidos, que son una aproximación de los caracteres percibidos por el usuario.

Tenga en cuenta que al procesar cadenas que contienen texto legible por humanos, se debe evitar el procesamiento carácter por carácter en la mayor medida posible. En su lugar, utilice algoritmos Unicode sensibles a la configuración regional de alto nivel, por ejemplo,
String.localizedStandardCompare(),
String.localizedLowercaseString,
String.localizedStandardRangeOfString() etc.

Rápido 5.2

let str = "abcdef"
str[1 ..< 3] // returns "bc"
str[5] // returns "f"
str[80] // returns ""
str.substring(fromIndex: 3) // returns "def"
str.substring(toIndex: str.length - 2) // returns "abcd"

Deberá agregar esta extensión String a su proyecto (está completamente probado):

extension String 

    var length: Int 
        return count
    

    subscript (i: Int) -> String 
        return self[i ..< i + 1]
    

    func substring(fromIndex: Int) -> String 
        return self[min(fromIndex, length) ..< length]
    

    func substring(toIndex: Int) -> String 
        return self[0 ..< max(0, toIndex)]
    

    subscript (r: Range) -> String 
        let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
                                            upper: min(length, max(0, r.upperBound))))
        let start = index(startIndex, offsetBy: range.lowerBound)
        let end = index(start, offsetBy: range.upperBound - range.lowerBound)
        return String(self[start ..< end])
    


Aunque Swift siempre tuvo una solución inmediata a este problema (sin la extensión String, que proporcioné a continuación), todavía lo haría fuertemente recomendado usando la extensión. ¿Por qué? Porque me ahorró decenas de horas de dolorosa migración desde las primeras versiones de Swift, donde la sintaxis de String cambiaba casi en 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.

let str = "Hello, world!"
let index = str.index(str.startIndex, offsetBy: 4)
str[index] // returns Character 'o'

let endIndex = str.index(str.endIndex, offsetBy:-2)
str[index ..< endIndex] // returns String "o, worl"

String(str.suffix(from: index)) // returns String "o, world!"
String(str.prefix(upTo: index)) // returns String "Hell"

Se me ocurrió esta buena solución

var firstChar = Array(string)[0]

No se te olvide compartir este post si lograste el éxito.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *