map, filter y reduce con arreglos en Swift

Resumen

Cuando trabajas con arreglos en Swift, las funciones map, filter y reduce te permiten escribir menos código y hacerlo más eficiente. Aquí aprendes a aplicarlas en un caso real: un Students Manager que calcula promedios, filtra aprobados y consolida materias cursadas.

Cómo se calcula si un estudiante aprobó el semestre

Antes de saltar a las funciones avanzadas, conviene tener clara la lógica base. La idea es que un estudiante apruebe si pasó al menos el 60% de sus materias.

El enfoque que vimos en clase parte de una variable contadora y un recorrido por las materias [01:38]. Para cada materia, se valida la nota correspondiente con la función wasPassed y, si la condición se cumple, el contador sube en uno. Al final, se compara el porcentaje de materias aprobadas contra el umbral del 60%.

La segunda función, getAverageScore, suma todas las notas y divide entre el total. Devuelve un double y aplica la fórmula básica de promedio [02:48].

¿Qué hace la función isApproved en Swift? Recorre las materias del estudiante, cuenta cuántas pasó según su nota y retorna true si superó el 60% de aprobación.

Cómo filtrar arreglos en Swift con la función filter

La función filter te permite quedarte solo con los elementos que cumplen una condición booleana. En lugar de escribir un for con un if dentro, le pasas una closure que devuelve true o false [04:13].

Para obtener a los estudiantes aprobados, la sintaxis larga queda así:

swift return students.filter { student in return student.isApproved }

Para los reprobados, basta con negar la condición:

swift return students.filter { student in return !student.isApproved }

La función recorre internamente cada estudiante y arma una lista nueva con los que pasan el filtro. Si el booleano es true, el elemento entra; si es false, se descarta.

Cómo transformar listas con map y reducirlas con reduce

Cuando necesitas convertir una lista en otra de un tipo distinto, map es la herramienta. Cuando necesitas colapsar una lista en un único valor, usas reduce.

Cómo mapear estudiantes a sus promedios con map

La función getAverages debe devolver una lista de doubles, uno por cada estudiante. Con map, transformas cada estudiante en su nota promedio en una sola línea [06:25]:

swift return students.map { student in return student.getAverageScore() }

Cada student se reemplaza por el resultado de getAverageScore, y obtienes un arreglo de tipo [Double] listo para usar.

¿Para qué sirve map en Swift? Para mapear cada elemento de un arreglo a otro valor, posiblemente de tipo distinto, sin escribir bucles manuales.

Cómo consolidar materias únicas con reduce

Para obtener todas las materias cursadas sin duplicados, usas reduce con un set vacío como valor inicial [07:16]. La función recibe dos parámetros: el resultado acumulado y cada estudiante.

swift return students.reduce(into: Set<Subject>()) { result, student in for subject in student.subjects { result.insert(subject) } }

Como los sets no admiten duplicados, si dos estudiantes cursan Matemáticas, en el resultado final aparece solo una vez. Reduce el arreglo completo en un único objeto.

Cómo sumar promedios con la notación corta de reduce

Para calcular el promedio de promedios, primero obtienes la lista con getAverages. Luego aplicas reduce con notación corta para sumar [09:00]:

swift let average = getAverages() return average.reduce(0.0, +) / Double(average.count)

El 0.0 indica que el valor inicial es de tipo double, y el operador + se pasa como función. Importante: tienes que convertir count a double con Double(average.count) porque en Swift solo puedes operar entre objetos del mismo tipo.

Por qué usar map, filter y reduce en lugar de bucles manuales

Estas funciones avanzadas no son solo azúcar sintáctica. Te ahorran líneas, reducen errores y dejan la intención del código más clara: cuando lees filter, sabes que estás seleccionando; cuando lees map, que estás transformando; cuando lees reduce, que estás colapsando.

Algunas ventajas concretas que viste en el ejercicio:

  • Menos variables temporales y contadores manuales.
  • Lógica encapsulada dentro de closures fáciles de leer.
  • Encadenamiento posible entre funciones para flujos más expresivos.

¿Probaste resolver el ejercicio antes de ver la solución? Cuéntame en los comentarios qué función te costó más y cómo la abordaste.