Ejemplos de función anónima y lambda para crear un Array



Vamos a ver un ejemplo sencillo para ilustrar la entrada Funciones de orden superior, anónimas y lambdas y concretamente el uso de una función anónima y una lambda. Con este pequeño ejemplo vamos a intentar demostrar que realmente las expresiones lambda son una forma simplificada de pasar una funcionalidad como parámetro sin la necesidad de crear funciones anónimas, lo cual es una ventaja al requerir menos código, lo que facilita su legibilidad.

El objetivo del ejercicio es crear un array de los diez primeros números pares.

Una primera aproximación podría ser:
fun main(args: Array<String>) {       
    
    val arrayPares = IntArray(10) // también: arrayOfNulls<Int>(10)      
 
    for (i in arrayPares.indices) {
        arrayPares[i] = (i + 1) * 2
    }
      
    for (numero in arrayPares) { // recorremos el array        
        print("$numero ") // 2 4 6 8 10 12 14 16 18 20
    }    
}
Otra opción para crear este array podría ser:
val arrayPares = IntRange(2, 20).step(2).toList().toIntArray()
Y aunque hay otras opciones muy eficientes (que veremos en futuras entradas), para lo que nos interesa ahora (funciones anónimas y lambdas), vamos a crear el array con el constructor de la clase Array, que requiere especificar su tamaño (el número de elementos que contiene) y el valor de cada elemento que es asignado a través de una función inicializadora que devuelve un valor para cada posición (para cada índice del array). Eso lo podemos hacer utilizando una función anónima de esta manera:
fun main(args: Array<String>) {
  
    // función anónima con parámetro entero que devuelve un número calculado a partir del parámetro
    val pares = fun(indice: Int) = (indice + 1) * 2
    
    val arrayPares = Array(10, pares) // limitamos a 10 el número de elementos admitidos

    for (numero in arrayPares) {
        print("$numero ") // 2 4 6 8 10 12 14 16 18 20
    }  
}
A partir del ejemplo anterior, vamos a simplificar el código antes de utilizar una lambda. Primero, nos podemos ahorrar la asignación de la función anónima a la variable pares, y la usamos directamente como parámetro en el constructor del array:
fun main(args: Array<String>) {     
    
    val arrayPares = Array(10, fun(indice: Int) = (indice + 1) * 2)

    for (numero in arrayPares) {
        print("$numero ") // 2 4 6 8 10 12 14 16 18 20
    }  
}
Recuerda que declaramos una lambda entre llaves dentro de las cuales separamos los parámetros del cuerpo con el operador -> siguiendo esta sintaxis:



Ahora podemos transformar la función anónima en una lambda:
fun main(args: Array<String>) {     
    
    val arrayPares = Array(10, { indice: Int -> (indice + 1) * 2 })    
    
    for (numero in arrayPares) {
        print("$numero ") // 2 4 6 8 10 12 14 16 18 20
    }  
}
Por último, recordando que Kotlin es un lenguaje conciso y que esta lambda solo tiene un parámetro, podemos omitir el parámetro en la declaración (y por tanto también el operador ->) y hacer referencia al parámetro con it:
fun main(args: Array<String>) {     
    
    val arrayPares = Array(10, { (it + 1) * 2 })
    
    for (numero in arrayPares) {
        print("$numero ") // 2 4 6 8 10 12 14 16 18 20
    }  
}
¡Listo! En este punto comprobamos que la lambda nos ha servido para simplificar el código al sustituir una función por una simple expresión de cálculo.

Pero podemos dar un paso más y evitar la variable arrayPares creando el array en el mismo momento de recorrerlo:
fun main(args: Array<String>) {           
    for (numero in Array(10, { (it + 1) * 2 })) {
        print("$numero ") // 2 4 6 8 10 12 14 16 18 20
    }  
}
Y todavía podemos reducirlo más recorriendo el array con forEach (aunque a veces hay que encontrar el equilibrio entre código conciso y legible):
fun main(args: Array<String>) {            
    Array(10, { (it + 1) * 2 }).forEach { print("$it ") }
}

Comentarios

Entradas populares

Recursos gratis para aprender Kotlin

I/O: entrada y salida de datos en consola

Lectura y escritura de archivos