Función elementAt En Kotlin

En este tutorial aprenderás a usar la función elementAt en Kotlin para obtener un elemento en una posición específica de una colección. Adicionalmente verás ejemplos con las variaciones elementArOrNull() y elementAtOrElse().

Función elementAt()

La función de extensión elementAt() recibe como parámetro el índice (index) entero del elemento que deseas retornar de una colección. Si el índice está por fuera de los límites de la colección, entonces se lanzará una excepción del tipo IndexOutOfBoundsException.

// Sintaxis de elementAt() en arreglos
fun <T> Array<out T>.elementAt(index: Int): T

// Sintaxis de elementAt() en iterables
fun <T> Iterable<T>.elementAt(index: Int): T

// Sintaxis de elementAt() en listas
fun <T> List<T>.elementAt(index: Int): T

Esta función es de gran utilidad para los tipos con ausencia de métodos de acceso indexado como los rangos y los sets.

Pero en el caso de las listas y los arreglos podremos conseguir el mismo resultado con el método get() y el uso de paréntesis ([]). Y es que la implementación de elementAt() para estos tipos es solo el recubrimiento de su propio acceso indexado:

public inline fun <T> List<T>.elementAt(index: Int): T {
    return get(index)
}

Ejemplo De elementAt()

Dado un conjunto el conjunto de números C = [10, 1, 2, 3, 4, 9], obtener los elementos del primer y último índice para promediarlos. El set debe estar ordenado en orden ascendente antes de aplicar las operaciones.

fun main() {
    val numbers = sortedSetOf(10, 1, 2, 3, 4, 9)
    val firstNumber = numbers.elementAt(0)
    val lastIndex = numbers.size - 1
    val lastNumber = numbers.elementAt(lastIndex)
    val avg = ((firstNumber + lastNumber) / 2.0)
    println(
        """
        elementAt(0) es $firstNumber
        elementAt($lastIndex) es $lastNumber
        El promedio es $avg
        """.trimIndent()
    )
}

Salida:

elementAt(0) es 1
elementAt(5) es 10
El promedio es 5.5

En primer lugar se crea el un set ordenado con la función sortedSetOf(). Luego se obtiene el primer elemento con elementAt(0). El último elemento usa el tamaño de la colección menos la unidad (n - 1) para conseguir el último elemento.

Al final obtenemos el promedio sumando ambos números y dividiendo por dos. Luego imprimimos los valores en un String multilínea.

Por otro lado, la obtención del primer y último elemento también pudo lograrse con las funciones first() y last().

val firstNumber = numbers.first()
val lastNumber = numbers.last()

Función elementAtOrNull()

A diferencia de elementAt(), la función elementAtOrNull() retorna null en vez de la excepción si el índice está fuera de rango.

Esta variante es de gran utilidad si consideras que es parte de tu lógica la posibilidad de que no se encuentre el elemento. Veamos algunos accesos a un rango de enteros:

fun main() {
    val range = 1..10
    println(range.elementAtOrNull(2))
    println(range.elementAtOrNull(3))
    println(range.elementAtOrNull(10))
}

Salida:

3
4
null

Función elementAtOrElse()

Usa a elementAtOrElse() para aumentar el control sobre el resultado obtenido, cuando el índice proporcionado está fuera de los límites de la colección. Recibe como segundo parámetro una función lambda para generar el valor por defecto en caso de que el índice sea inválido.

// Ejemplo de sintaxis para arreglos
inline fun <T> Array<out T>.elementAtOrElse(
    index: Int,
    defaultValue: (Int) -> T
): T

Tomemos como ejemplo un rango de caracteres del cual necesitamos obtener elementos por su índice para imprimir un código de 10 dígitos. El cálculo del índice es generado aleatoriamente entre los número 0 a 20. Si el índice es invalido, entonces usar como valor por defecto el literal '_'.

fun main() {
    val fromAToF = 'a'..'f'
    repeat(10) {
        val randomIndex = Random.nextInt(0, 20)
        val randomChar = fromAToF.elementAtOrElse(randomIndex) { '_' }
        print(randomChar)
    }
}

Salida aleatoria:

_cd__f__f_

La solución consiste en usar a la función repeat() para imprimir 10 caracteres. A través de Random.nextInt() obtenemos índices del 0 al 20 y luego imprimimos el resultado de elementArOrElse() pasando como valor por defecto la raya al piso.

En la salida veremos múltiples rayas debido que el tamaño del rango es 6, por lo que es muy probable obtener índices fuera de este límite.

Únete Al Discord De Develou

Si tienes problemas con el código de este tutorial, preguntas, recomendaciones o solo deseas discutir sobre desarrollo Android conmigo y otros desarrolladores, únete a la comunidad de Discord de Develou y siéntete libre de participar como gustes. ¡Te espero!