Curso Kotlin | #6. Tipos Char y CharSequence
Tags: kotlin, spanish, beginners, programming
Published: 2022-12-13 13:28:58

Bienvenido/a a otro capítulo del Curso de Kotlin! Podés consultar el curso completo desde [este link](https://github.com/maxwellnewage/kotlin-course) que te dejo acá. Podés seguirme por [LinkedIn](https://www.linkedin.com/in/maximilianoburgos/) o [Twitter](https://twitter.com/maxwellnewage) 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:

```kotlin
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:

```kotlin
val name: String = "Max"
```

Vamos a comprobar que se trata justamente de un arreglo de 3 valores tipo Char:

![Debug Char](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7opitle2ukqbbr3mw8q.png)

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:

```kotlin
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:

```kotlin
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.

```kotlin
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:

```kotlin
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:

```kotlin
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:

```kotlin
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:

```kotlin
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í](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char/).

### 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:

```kotlin
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:

```kotlin
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:

```kotlin
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.

```kotlin
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:

```kotlin
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:

```kotlin
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](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char-sequence/).

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!