JavaScript

Higher-Order Functions em JavaScript: map, filter, reduce e Composição na Prática

7 min de leitura

Higher-Order Functions em JavaScript: map, filter, reduce e Composição na Prática

O que são Higher-Order Functions? Higher-Order Functions (HOF) são funções que recebem outras funções como argumentos ou retornam funções como resultado. Elas são fundamentais na programação funcional e permitem escrever código mais reutilizável, expressivo e modular. Em JavaScript, como tudo é um objeto — inclusive funções — trabalhar com HOF é natural e poderoso. O grande benefício é a abstração: em vez de escrever loops repetitivos, você descreve o que quer fazer com seus dados. Isso torna o código mais legível e menos propenso a erros. Vamos explorar as três HOFs mais importantes: , e . Map, Filter e Reduce na Prática Map: Transformar Dados aplica uma função a cada elemento de um array e retorna um novo array com os resultados. Use-o quando quiser transformar todos os itens de forma igual. Filter: Selecionar Dados cria um novo array contendo apenas os elementos que passam em um teste. Use-o para remover ou selecionar itens baseado em uma condição. Reduce: Agregar

<h2>O que são Higher-Order Functions?</h2>

<p>Higher-Order Functions (HOF) são funções que recebem outras funções como argumentos ou retornam funções como resultado. Elas são fundamentais na programação funcional e permitem escrever código mais reutilizável, expressivo e modular. Em JavaScript, como tudo é um objeto — inclusive funções — trabalhar com HOF é natural e poderoso.</p>

<p>O grande benefício é a abstração: em vez de escrever loops repetitivos, você descreve <em>o que</em> quer fazer com seus dados. Isso torna o código mais legível e menos propenso a erros. Vamos explorar as três HOFs mais importantes: <code>map</code>, <code>filter</code> e <code>reduce</code>.</p>

<h2>Map, Filter e Reduce na Prática</h2>

<h3>Map: Transformar Dados</h3>

<p><code>Map</code> aplica uma função a cada elemento de um array e retorna um novo array com os resultados. Use-o quando quiser <strong>transformar</strong> todos os itens de forma igual.</p>

<pre><code class="language-javascript">const numeros = [1, 2, 3, 4, 5];

const dobrados = numeros.map(n =&gt; n * 2);

console.log(dobrados); // [2, 4, 6, 8, 10]

// Exemplo real: converter objetos de uma API

const usuarios = [

{ id: 1, nome: &quot;Ana&quot; },

{ id: 2, nome: &quot;Bruno&quot; }

];

const nomes = usuarios.map(u =&gt; u.nome);

console.log(nomes); // [&quot;Ana&quot;, &quot;Bruno&quot;]</code></pre>

<h3>Filter: Selecionar Dados</h3>

<p><code>Filter</code> cria um novo array contendo apenas os elementos que passam em um teste. Use-o para <strong>remover ou selecionar</strong> itens baseado em uma condição.</p>

<pre><code class="language-javascript">const numeros = [1, 2, 3, 4, 5, 6];

const pares = numeros.filter(n =&gt; n % 2 === 0);

console.log(pares); // [2, 4, 6]

// Exemplo real: listar apenas usuários ativos

const usuarios = [

{ id: 1, nome: &quot;Ana&quot;, ativo: true },

{ id: 2, nome: &quot;Bruno&quot;, ativo: false },

{ id: 3, nome: &quot;Carlos&quot;, ativo: true }

];

const ativos = usuarios.filter(u =&gt; u.ativo);

console.log(ativos); // Ana e Carlos</code></pre>

<h3>Reduce: Agregar Dados</h3>

<p><code>Reduce</code> acumula valores em um único resultado, passando por cada elemento. Use-o para <strong>sumarizar</strong> dados: somas, contagens, agregações ou transformações complexas.</p>

<pre><code class="language-javascript">const numeros = [1, 2, 3, 4, 5];

const soma = numeros.reduce((acumulador, atual) =&gt; acumulador + atual, 0);

console.log(soma); // 15

// Exemplo real: contar ocorrências de palavras

const palavras = [&quot;gato&quot;, &quot;cão&quot;, &quot;gato&quot;, &quot;pato&quot;, &quot;cão&quot;, &quot;cão&quot;];

const contagem = palavras.reduce((acc, palavra) =&gt; {

acc[palavra] = (acc[palavra] || 0) + 1;

return acc;

}, {});

console.log(contagem); // { gato: 2, cão: 3, pato: 1 }</code></pre>

<h2>Composição de Higher-Order Functions</h2>

<p>Composição é combinar múltiplas funções pequenas para resolver problemas complexos. A beleza é que <code>map</code>, <code>filter</code> e <code>reduce</code> retornam arrays (ou valores), permitindo encadeamento natural.</p>

<pre><code class="language-javascript">const usuarios = [

{ id: 1, nome: &quot;Ana&quot;, salario: 3000, ativo: true },

{ id: 2, nome: &quot;Bruno&quot;, salario: 2500, ativo: false },

{ id: 3, nome: &quot;Carlos&quot;, salario: 4000, ativo: true }

];

// Problema: somar salários apenas de usuários ativos

const totalAtivos = usuarios

.filter(u =&gt; u.ativo)

.map(u =&gt; u.salario)

.reduce((acc, sal) =&gt; acc + sal, 0);

console.log(totalAtivos); // 7000 (Ana + Carlos)</code></pre>

<p>Esse padrão é extremamente legível: filtro → extraio salários → somo. Para problemas ainda mais complexos, crie funções compostas reutilizáveis:</p>

<pre><code class="language-javascript">// Criar predicados e transformadores reutilizáveis

const ehAtivo = u =&gt; u.ativo;

const extrairSalario = u =&gt; u.salario;

const somar = (acc, val) =&gt; acc + val;

// Aplicar em qualquer contexto

const totalAtivos = usuarios

.filter(ehAtivo)

.map(extrairSalario)

.reduce(somar, 0);

// Outra composição: média salarial

const quantidadeAtivos = usuarios.filter(ehAtivo).length;

const mediaAtivos = totalAtivos / quantidadeAtivos;

console.log(mediaAtivos); // 3500</code></pre>

<h2>Criando Funções Compostas Avançadas</h2>

<h3>Função Compose Genérica</h3>

<p>Uma função <code>compose</code> recebe múltiplas funções e as aplica em sequência. Isso é programação funcional pura:</p>

<pre><code class="language-javascript">// Compose: aplica funções da direita para esquerda

const compose = (...funcs) =&gt; valor =&gt;

funcs.reduceRight((acc, func) =&gt; func(acc), valor);

// Funções básicas

const adicionar10 = x =&gt; x + 10;

const multiplicarPor2 = x =&gt; x * 2;

const dividirPor5 = x =&gt; x / 5;

// Compor: (((5 * 2) + 10) / 5)

const pipeline = compose(dividirPor5, adicionar10, multiplicarPor2);

console.log(pipeline(5)); // 4

// Pipe: aplica da esquerda para direita (mais intuitivo)

const pipe = (...funcs) =&gt; valor =&gt;

funcs.reduce((acc, func) =&gt; func(acc), valor);

const processamento = pipe(multiplicarPor2, adicionar10, dividirPor5);

console.log(processamento(5)); // 4</code></pre>

<h3>Exemplo Real: Processamento de Dados</h3>

<pre><code class="language-javascript">const dados = [

{ nome: &quot;Alice&quot;, idade: 25, ativo: true },

{ nome: &quot;Bob&quot;, idade: 17, ativo: false },

{ nome: &quot;Carol&quot;, idade: 30, ativo: true }

];

// Predicados e transformadores específicos

const maioresDeIdade = p =&gt; p.idade &gt;= 18;

const ehAtivo = p =&gt; p.ativo;

const extrairNome = p =&gt; p.nome;

// Composição prática

const nomesMaioresEAtivos = dados

.filter(maioresDeIdade)

.filter(ehAtivo)

.map(extrairNome);

console.log(nomesMaioresEAtivos); // [&quot;Alice&quot;, &quot;Carol&quot;]

// Ou com um único filter (otimizado):

const nomesMaioresEAtivos2 = dados

.filter(p =&gt; maioresDeIdade(p) &amp;&amp; ehAtivo(p))

.map(extrairNome);</code></pre>

<h2>Conclusão</h2>

<p>Higher-Order Functions são pilares da programação moderna em JavaScript. Ao dominar <code>map</code> para transformações, <code>filter</code> para seleções e <code>reduce</code> para agregações, você escreve código declarativo e robusto. Composição de HOFs permite resolver problemas complexos de forma elegante e legível — é o caminho para se tornar um desenvolvedor mais eficiente. Pratique combinando essas funções em seus projetos reais e perceba como seu código fica mais profissional e manutenível.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/map" target="_blank" rel="noopener noreferrer">MDN Web Docs - Array.prototype.map()</a></li>

<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/filter" target="_blank" rel="noopener noreferrer">MDN Web Docs - Array.prototype.filter()</a></li>

<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce" target="_blank" rel="noopener noreferrer">MDN Web Docs - Array.prototype.reduce()</a></li>

<li><a href="https://eloquentjavascript.net/05_higher_order.html" target="_blank" rel="noopener noreferrer">Eloquent JavaScript - Capítulo sobre Funções de Ordem Superior</a></li>

<li><a href="https://github.com/getify/You-Dont-Know-JS" target="_blank" rel="noopener noreferrer">You Don&#039;t Know JS Yet - Functional Programming</a></li>

</ul>

Comentários

Mais em JavaScript

Dominando Módulos Nativos do Node.js: fs, path, os e crypto em Projetos Reais
Dominando Módulos Nativos do Node.js: fs, path, os e crypto em Projetos Reais

Introdução aos Módulos Nativos do Node.js O Node.js fornece diversos módulos...

Guia Completo de Operadores em JavaScript: Aritméticos, Lógicos, Ternário e Nullish
Guia Completo de Operadores em JavaScript: Aritméticos, Lógicos, Ternário e Nullish

Operadores Aritméticos: Os Pilares das Contas Os operadores aritméticos são f...

Boas Práticas de Tipos Avançados em TypeScript: Union, Intersection, Generics e Utility Types para Times Ágeis
Boas Práticas de Tipos Avançados em TypeScript: Union, Intersection, Generics e Utility Types para Times Ágeis

Union Types: Combinando Múltiplos Tipos Union types permitem que uma variável...