Curso Kotlin | #6. Tipos Char y CharSequence
Maximiliano Burgos
Posted on December 13, 2022
Bienvenido/a a otro capítulo del Curso de Kotlin! Podés consultar el curso completo desde este link que te dejo acá. Podés seguirme por LinkedIn o Twitter si querés estar al tanto de las próximas publicaciones.
Que es un tipo Char?
El tipo Char viene de character, el cual se representa un único carácter:
val letter: Char = 'a'
Se usan comillas simples, porque si usamos dobles estamos haciendo referencia a un String y nos va a dar error.
Cuando decíamos que un tipo String es una cadena de caracteres, ahora podríamos aclarar que es un arreglo (o array) de chars.
Por ejemplo, si debuggeo la famosa variable name que teníamos en la clase anterior:
val name: String = "Max"
Vamos a comprobar que se trata justamente de un arreglo de 3 valores tipo Char:
Más adelante explicaremos que es un array y como recorrerlo. No obstante, para entender este ejemplo, digamos que un tipo String esta compuesto por un grupo de chars.
Si quisieramos acceder al char ‘M’, lo haríamos de la siguiente manera:
println(name[0])
Comprender la composición de un String y las características de Char nos van a permitir entender con mas detenimiento cada uno de sus métodos, especialmente los de búsqueda.
Ahora veamos cuáles son esos métodos de Char.
Método isDigit
Si queremos saber si un carácter es numérico, podemos usar este método:
println(letter.isDigit())
#output: false
Casteos
Puede que queramos convertir un tipo de variable en otra. Por ejemplo un Char a String, Int, Float o cualquier otro que necesitemos en otro momento.
println("${letter.toInt()}")
#output: 97
¿Qué significa ese 97? Nosotros teníamos una ‘a’. Ese es el valor ASCII de un caracter.
Si bien esto nos puede resultar útil en otro momento, ahora necesitamos otro tipo de conversión. Ésta es la que buscamos:
println("${letter.digitToInt()}")
Importante: El método digitToInt es experimental, por lo cual debemos agregar la annotation @ExperimentalStdlibApi en nuestro método.
Si corremos esto, nos va a arrojar una excepción:
Exception in thread “main” java.lang.IllegalArgumentException: Char a is not a decimal digit
at kotlin.text.CharsKt__CharKt.digitToInt(Char.kt:26)
at MainKt.main(main.kt:8)
La parte importante es: Char a is not a decimal digit.
El problema radica en que no podemos transformar una letra “a” en entero, por obvias razones. Asi que vamos a cambiarlo a un número:
val letter: Char = '1'
println("${letter.digitToInt()}")
#output: 1
Y esto nos va a arrojar un número que podemos usar para operar, como veremos mas adelante.
Otro detalle interesante, es que si queremos convertir el char en un String e imprimirlo, println lo toma como redundante:
println("${letter.toString()}")
Porque el método println soporta Char, y de una forma indirecta String hereda a Char (String > CharSequence > Char).
Hay otros casteos, pero prefiero mencionarlos en clases posteriores, para no marear y además porque van a ser mas entendibles aplicados a tipos más complejos. Podés verlos aquí.
CharSequence
Este tipo de dato representa, como sus palabras lo dicen, una secuencia de chars. Hereda de Char y es el causante de que comencemos a llamar a los strings como cadenas de caracteres.
Un tipo CharSequence ya puede accederse como un array, y posee los métodos mas importantes que luego utilizará su hijo, el String:
val numbers: CharSequence = "123"
println("${numbers[0]}")
#output: 1
Como ven, ya se necesitan las comillas dobles con este tipo de dato.
Veamos alguno de sus mejores métodos.
Método Filter
Probablemente uno de los métodos más importantes en Kotlin.
En el método isDigit(), recibíamos un true o false dependiendo del contenido del Char. Ahora con CharSequence tenemos una forma de recorrer, validar y cortar esa cadena:
val password: CharSequence = "Maxwell123"
val numbersInPw: CharSequence = password.filter { it.isDigit() }
println(numbersInPw)
#output: 123
Primero tenemos una variable password que contiene números y letras. Luego usamos el método filter y preguntamos dentro (it es igual a la variable password) si es un dígito.
Esto internamente va a recorrer Char a Char para verificar si es o no un dígito.
El resultado se almacena en numbersInPw, otro CharSequence retornado por filter. Luego se imprime el valor.
Método Filter Indexed
Puede que necesitemos el índice de cada valor que recorre el filter. Para eso tenemos este método:
val numbersInPw: CharSequence = password.filterIndexed { index, value ->
println("Index: $index")
value.isDigit()
}
println(numbersInPw)
Esto devolverá un print por cada indice que itera, lo cual significa que será del 0 al 9 por nuestra cadena “Maxwell123”.
En cuanto al filtro, funciona igual al anterior, por lo tanto va a seguir almacenando en numbersInPw el valor “123”.
Quizá hayas notado que dentro de nuestra función lambda (abordaremos mucho mas sobre este concepto en los próximos capítulos) tenemos index y value cuando antes teníamos “it”.
Esto ocurre porque “it” es el nombre por defecto, y como tenemos dos valores de retorno que necesitamos manejar, estamos obligados a darles un nombre explícito.
Lo recomendable es hacerlo siempre, incluso con uno, por una cuestión de dejar en claro el significado del valor que estamos tratando.
Método subSequence
Si necesitamos cortar la cadena a mano, este método es el indicado.
val numbersInPw: CharSequence = password.subSequence(0, 3)
println(numbersInPw)
#output: Max
Indicamos como parámetros el índice 0 (la M) y el 3 (la w). Puede resultar confuso porque queremos hasta el índice 2 (la x), pero debemos tener en cuenta que esta función nos corta la cadena hasta el último índice no incluido.
Método Find
Este método nos va a permitir encontrar la primer ocurrencia del Char y almacenarla. Es como filter, pero solo itera una vez:
val numbersInPw: Char? = password.find { it.isDigit() }
println(numbersInPw)
#output: 1
Habrás notado que devuelve un Char con un signo “?”: Eso significa que es un nullable Char. Veremos este tema en detalle posteriormente, pero para resumir, esto implica que numbersInPw podría devolver null si no encuentra un dígito (en este caso) en nuestra cadena.
Método First
Este método devuelve el primer caracter de nuestra cadena:
println(password.first())
#output: M
Es el equivalente a escribir algo como password[0]. La diferencia radica que en el primer caso usamos una función, y en el segundo estamos accediendo desde el índice de nuestro arreglo.
Conclusión
Existen muchos métodos más en CharSequence, y pueden encontrarlos en la documentación oficial.
A lo largo de las clases vamos a trabajar con los mencionados arriba, pero seguramente usemos alguno nuevo.
Espero que hayan disfrutado el artículo y ¡preparen los motores porque en los próximos empezamos a poner en práctica todo!
¡Nos vemos en el siguiente!
Posted on December 13, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.