En artículos ateriores habíamos visto cóm omejorar la arquiectura de nuestro código mediante patrones de diseño y el uso de los principios SOLID. Ahora veremos cómo mejorar el código Swift con funciones de orden superior. Seguramente más de una vez las has utilizado, pero, ¿qué son y cómo mejora tu código Swift con funciones de orden superior?

Funciones de orden superior en Swift

Las funciones de orden superior son funciones que toman como argumentos otras funciones o cierres (closures) y que devuelven una función o un cierre (closure). Estas funciones se utilizan con arrays, sets y dictionaries, y actúan sobre los elementos que contienen (esto se hace mediante métodos que se aplicación sobre lo elementos de la colección mediante la sintaxis de punto).

Algunas de las funciones más conocidas son map, compactMap, flatMap, reduce, filter, contains, sorted, forEach, o removeAll.

map

La función map actúa realizando una operación sobre todos los elementos de una colección y devolviendo una nueva colección con los resultados de dicha operación.

Por ejemplo, vamos a suponer que tenemos un array con varias palabras con todas sus letras en minúscula y queremos obtener un nuevo array con cada una de estas palabras pero con todas las letras en mayúscula. Esto lo podríamos hacer con un bucle for…in:

Vamos a ver cómo hacerlo con la función map. Tal como se muestra en la documentación de Apple, map se declara como:

Donde transform acepta un elemento de una colección o secuencia como parámetro y devuelve un valor transformado del mismo tipo o de otro diferente.

En el ejemplo que estamos viendom lo aplicamos de la siguiente manera:

Lo que hace map es recorrer todo el array de elementos, applicar el método uppercased() en cada uno de ellos y devolver un nuevo array con estos valores.

De todas formas, podemos reducir esta expresión haciendo uso del argumento abreviado $0, con el cual se hace referencia a cualquier elementos del array:

compactMap

Supongamos ahora que dentro del array del ejemplo anterior hay valores nulos (nil). Si utilizamos la función map, deberemos tener en cuenta si el valor sobre el que se actúa es nulo (nil) o no lo es:

Pero, ¿y si lo que queremos en realidad es obtener el nuevo array pero sin los valores nulos? Para conseguir esto tenemos la función compactMap.

La funció compactMap devuelve un array que contiene los resultados no nulos (nil) tras aplicar la transformación dada a cada elemento de una secuencia.

Por tanto, en el ejemplo que estamos viendo:

Es decir, compactMap recorre todos los elementos del array y aplica el método a los valores no nulos, devolviéndolos en un array, en este caso del tipo [String] (es decir, el valor de String no es opcional).

flatMap

La función flatMap nos permite transformar un array de arrays en un único array que contiene todos los elementos. Tal como lo declara Apple en su documentación:

Por ejemplo, veamos primero cómo lo haríamos sin flatMap:

Pero con flatMap podemos simplificar el código de la siguiente manera:

reduce

reduce es una función que, al aplicarla sobre una colección, nos devuelve el resultado de combinar los elementos de dicha colección:

Por ejemplo, si tenemos un array con los números del 1 al 10 y queremos obtener sus suma. Podemos hacerlo de la siguiente forma sin utilizar la función reduce:

Con reduce, simplemente hacemos lo siguiente:

En la primera iteración el valor de x es 0 (tal como lo hemos indicado en la función) y el valor de y es 1. Por lo que el resultado x + y será 1. En la segunda iteración x es 1 e y es 2, por lo que el resultado será 3. Y así sucesivamente.

De una forma más simplificada podemos escribir:

filter

Tal como su nombre indica, la función filter filtra el contenido de una colección y devuelve una nueva colección que contiente lo elementos que cumplen una determinada condición:

Por ejemplo, supongamos que tenemos la colección de palabras de los primeros ejemplos y queremos obtener una nueva colección con las palabras que contengan la letra ‘o’. Sin la función filter, lo podríamos hacer de la siguiente forma:

En este caso, no hemos utilizado la funcion contains ya que como veremos más adelante, también es una funcion de orden superior.

Ahora vamos a simplificar este código usando la función filter:

Pero no tiene porqué aplicarse una única condición, podemos aplicar varias condiciones. Por ejemplo, en el caso anterior podemos hacer que nos devuelva las palabras que contengan la vocal ‘o’ y cuya longitud sea de 5 caracteres o más:

contains

En el ejemplo anterior hemos utilizado la función contains para determinar si una palabra contenía la vocal ‘o’. Pues bien, contains es un función de orden superior que permite comprobar si hay elementos que cumplen una determinada condición y devolver true o false según la cumpla o no.

Tal como indica Apple en su documentación, contains devuelve un valor booleano que indica si la secuencia contiene el elemento dado.

sorted

En numerosas ocasiones nos encontramos con una colección de elementos que queremos ordenar de alguna manera para mostrarlos. Por ejemplo, en los ejemplos del array de palabras vistos hasta ahora, dichas palabras no están ordenadas alfabéticamente.

Pero, ¿y si las quisieramos ordenar alfabéticamente? Podríamos utilizar algún algoritmo, como:

Este código lo podrímaos reducir utilizando el método swapAt, que nos permite intercamiar las posiciones de dos elementos en una secuencia:

Para reducir más este código, podemos utilizar la función sorted. Esta función nos devuelve los elementos de una secuencia ordenados de forma ascendente (siempre y cuando los elementos de la colección adopten el protocolo Comparable):

Por otro lado, si queremos utilizar nuestra propia condición para ordenar la colección, utilizamos la función sorted(by:), que tal como indica Apple en su documentación, devuelve los elementos de la secuencia, ordenados usando el predicado dado como la comparación entre elementos.

Por ejemplo, si queremos que las palabras estén ordenadas de orden alfabético inverso podemos hacer lo siguiente:

En este caso, al indicar el símbolo ‘>’ ordenamos la colección en orden descendente.

forEach

Cumple una función similar a for…in, pero a diferencia de este, no se puede utilizar ni continue ni break dentro de forEach, solo return:

removeAll

La función de orden superior removeAll(where:) nos permite eliminar los elementos de una secuencia que cumplan ciertas condiciones:

Por ejemplo, si queremos eliminar todos los números pares de una secuencia, podemos hacer lo siguiente mediante removeAll:

La potencia de removeAll(where:) se ve de forma más clara en el ejemplo que muestra Apple en su documentación, en el que lo utiliza para eliminar las vocales de una frase:

Concatenación de funciones

Las funciones de primer orden se pueden aplicar de forma consecutiva, concatenda. Por ejemplo, podemos tomar un array que contenga arrays de números y calcular sus suma:

Primero aplicamos la funcion flatMap para obtener un array con todos los números. Luego aplicamos la función reduce para sumarlos.

Conclusiones

Acabamos de ver algunas de las funciones de orden superior más utilizadas y su potencia mediante algunos ejemplos. Estas funciones permiten, por un lado, reducir la cantidad de código y por otro hacerlo más claro y conciso.

Categorías: Swift

0 comentarios

Deja una respuesta

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

Sígueme en Feedly
shares