flatMap es una operación muy común en programación funcional.
La idea es simple: aplicamos una función a cada elemento de una colección, pero esa función devuelve otra colección.
Por ejemplo:
[1, 2, 3]
Aplicamos:
x -> [x, x * 10]
Con un map obtendríamos:
[[1, 10], [2, 20], [3, 30]]
Con flatMap obtenemos:
[1, 10, 2, 20, 3, 30]
En otras palabras: flatMap = map + flatten
¿Cómo hacemos flatMap en C++23?
C++ no tiene una función llamada flatMap, pero podemos conseguir el mismo comportamiento utilizando std::views::transform y std::views::join.
#include <iostream>
#include <ranges>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3};
auto result = numbers
| std::views::transform([](int x) {
return std::vector{x, x * 10};
})
| std::views::join;
for (auto value : result) {
std::cout << value << " ";
}
}
Resultado: 1 10 2 20 3 30
Lo que ocurre es:
transform
produce:
[[1, 10], [2, 20], [3, 30]]
Y luego: join
aplana el resultado:
[1, 10, 2, 20, 3, 30]
Por lo tanto, en C++23 podemos pensar que:
transform(...) | join
es el equivalente a:
flatMap(...)
En Scala se puede hacer : numbers.flatMap(x => List(x, x * 10))
En Java:
numbers.stream()
.flatMap(x -> Stream.of(x, x * 10))
.toList();
Y en C++23:
numbers
| std::views::transform(...)
| std::views::join;
Distinta sintaxis, misma idea: flatMap = transformar + aplanar
Y aunque C++ no tenga un flatMap directamente en su biblioteca estándar, con Ranges podemos expresar el mismo concepto de una forma bastante declarativa.
