Quem tem medo do reduce? Entenda esse método agora ou seu dinheiro de volta
Tags: reduce, javascript, array, githubbrasil
Published: 2023-11-29 00:36:30

## Veja os diferentes tipos de operações que o reduce pode aplicar em uma array. Entenda esse método agora, ou devolvo seu dinheiro.
 
Reduce em inglês é **reduzir**.
 
O motivo disso é que a principal funcionalidade do reduce é **reduzir uma array a apenas um valor**. Veja um exemplo onde o reduce soma todos os números de uma array e retorna um número:
 
![array com os números 76, 23, 89 e 54 sendo reduzida ao número 242 através de uma soma](https://demenezes.dev/_next/image/?url=https%3A%2F%2Fwww.datocms-assets.com%2F64896%2F1700832228-array-com-os-numeros-76-23-89-e-54-sendo-reduzida-ao-numero-242-atraves-de-uma-soma.png%3Fauto%3Dformat&w=3840&q=75)
 
```javascript
const numbers = [ 76, 23, 89, 54 ];

const result = numbers.reduce(function(acumulado, atual) {
  return acumulado + atual;
});

console.log(result); // 242
```
 
O que está aconteceu aqui:
 
- Na primeira iteração,  `acumulado` é o primeiro da array, e `atual` o segundo
- Nas próximas, `acumulado` é o retorno das iterações anteriores, e o`atual` é o próximo item da array
- Apesar de a array ter 4 itens, houve apenas 3 iterações (vou mostrar como corrigir isso)
 
O valor que o reduce retorna não precisa ser apenas uma string ou número, pode ser um objeto e inclusive outra array.
 
Imagino que por esse motivo esse seja o método de array mais complicado de entender, não vou mentir. Mas estou aqui para tentar explicar tudo da melhor forma. Ao longo do post vou dar vários exemplos de uso do reduce, do mais fácil para o menos fácil, para ajudar na explicação.
 
O parâmetro do reduce é uma função callback. Porém existe um segundo parâmetro opcional (mas altamente recomendado) que muda um pouco a lógica do jogo.
 
## O valor inicial do reduce
 
Você pode definir um ponto de partida para o reduce.
 
O segundo parâmetro, que é opcional e não usei antes, é o **valor inicial**. Vou recriar o primeiro exemplo com um valor inicial de 8:
 
```javascript
const numbers = [ 76, 23, 89, 54 ];

function callback(acumulado, atual) {
  return acumulado + atual;
}

const initialValue = 8;

const result = numbers.reduce(callback, initialValue);

console.log(result); // 250
```
 
Coloquei cada parâmetro em uma variável para facilitar a leitura. Como o reduce inicia em 8, o resultado que antes era 242, agora é 250.
 
Mas agora, o valor das variáveis `acumulado` e `atual` muda durante as iterações:
 
- Agora, a quantidade de iterações corresponde ao número de itens da array, 4. Então por segurança, sempre defina o valor inicial
- Na primeira iteração, `acumulado` é o valor que defini como inicial (8); e `atual` representa o primeiro item da array, 76
- Nas próximas, `acumulado` é o resultado das iterações anteriores, e o `atual` é um item da array
 
**Colocar um valor inicial é como colocar um item no começo da array antes de começar o reduce**. Ele facilita o entendimento, porque na primeira iteração não existe **resultado anterior**.
 
No código abaixo, eu adicionei o 8 no começo da array e removi ele do valor inicial do Reduce. O resultado é o mesmo, mas não recomendo fazer isso. O valor inicial esclarece melhor o que acontece no código.
 
Faça por sua conta e risco:
 
```javascript
// Adicionei o 8 no começo da array
const numbers = [ 8, 76, 23, 89, 54 ];

function callback(acumulado, atual) {
  return acumulado + atual;
}

// Sem initialValue
const result = numbers.reduce(callback);

console.log(result); // 250
```
 
Aos poucos, fica claro que o valor de retorno da função callback é muito importante. Vou dar um foco nela agora.
 
## O retorno da função callback do reduce
 
Você pode retornar o que quiser.
 
**O valor que você retornar em cada iteração será o valor do `acumulado` na próxima**. Esse é uma das grandes vantagens do reduce, você pode fazer operações com mais de um item da array.
 
Existe apenas uma exceção a isso, que é a última iteração. O retorno dela é o resultado final do método reduce:
 
![tabela mostrando que o retorno da função callback de uma iteração define o valor do parâmetro acumulado na próxima](https://demenezes.dev/_next/image/?url=https%3A%2F%2Fwww.datocms-assets.com%2F64896%2F1700832320-tabela-mostrando-que-o-retorno-da-funcao-callback-de-uma-iteracao-define-o-valor-do-parametro-acumulado-na-proxima.png%3Fauto%3Dformat&w=3840&q=75)
 
Veja isso com um exemplo. Vou usar a array abaixo para fazer o reduce:
 
```javascript
const products = [
  { id: '1a2b3c4d', name: 'Camiseta Básica', color: 'Branca', size: 'M',     price: 200 },
  { id: '5e6f7g8h', name: 'Calça Jeans',     color: 'Azul',   size: 'L',     price: 500 },
  { id: '9i0j1k2l', name: 'Bolsa de Couro',  color: 'Marrom', size: 'Único', price: 800 },
  { id: '3m4n5o6p', name: 'Tênis Esportivo', color: 'Preto',  size: '42',    price: 300 },
  { id: '7q8r9s0t', name: 'Vestido Floral',  color: 'Rosa',   size: 'S',     price: 350 }
];
```
 
Essa array representa os produtos de um carrinho de compras. Como faço para chegar no valor total dos produtos ao final do carrinho?
 
Para começar, crio a função callback ainda vazia, e o valor inicial como zero:
 
```javascript
function callback(acumulado, produtoAtual) {
  
}

const initialValue = 0;

const result = products.reduce(callback, initialValue);
```
 
Agora preciso somar o valor de todos os produtos:
 
- O `acumulado` possui o valor inicial na primeira iteração, e o resultado anterior nas próximas
- E `produtoAtual` será, claro, o produto atual
- Então basta eu somar o `acumulado` com o preço do produto atual
 
```javascript
function callback(acumulado, produtoAtual) {
  return acumulado + produtoAtual.price
}

const initialValue = 0;

const result = products.reduce(callback, initialValue);

console.log(result); // 2150
```
 
E assim verá que o preço total desse carrinho é R$ 2150.
 
Como falei no começo, o reduce talvez seja um dos métodos mais chatinhos de entender. É difícil decidir o momento de usá-lo, já que é complexo e tem múltiplas possibilidades de uso. Uma dessas complexidades é que o reduce pode funcionar no lugar de outros métodos.
 
## O reduce pode substituir outros métodos de array
 
Olha que flexível.
 
Os próximos exemplos servem apenas para você compreender as possibilidades do reduce. Mas em todos eles, você verá que usar o outro método é muito mais simples.
 
Então muito juízo nos usos e:
 
> *Guarde o que foi bom<br>E jogue fora o que restou*
>> *"NX Zero"*
 
### Reduce ou map?
 
O sol nasce, o sapo sapeia, e o map mapeia.
 
**O map é um método Javascript que cria uma array a partir de outra, sem alterar a original.**
 
Para mais detalhes, veja esse [artigo sobre map](https://demenezes.dev/posts/map-javascript-array/) que escrevi no blog.
 
Com o map, vou pegar uma array com personagens de Dragon Ball, e colocar o nome deles em caixa alta. Mas apenas dos personagens da raça `terráqueo`:
 
```javascript
const characters = [
  { name: 'Goku',        race: 'saiyajin'     },
  { name: 'Cell',        race: 'android'      },
  { name: 'Kuririn',     race: 'terráqueo'    },
  { name: 'Bulma',       race: 'terráqueo'    },
  { name: 'Vegeta',      race: 'saiyajin'     },
  { name: 'Mestre Kame', race: 'terráqueo'    },
  { name: 'Kami-Sama',   race: 'namekuseijin' }
];

const result = characters.map(function(character) {
  if (character.race === 'terráqueo') {
    return {
      name: character.name.toUpperCase(),
      race: character.race
    };
  } else {
    return {
      name: character.name,
      race: character.race
    };
  }  
});

console.log(result);

/*
  [
    { "name": "Goku",        "race": "saiyajin"     },
    { "name": "Cell",        "race": "android"      },
    { "name": "KURIRIN",     "race": "terráqueo"    },
    { "name": "BULMA",       "race": "terráqueo"    },
    { "name": "Vegeta",      "race": "saiyajin"     },
    { "name": "MESTRE KAME", "race": "terráqueo"    },
    { "name": "Kami-Sama",   "race": "namekuseijin" }
  ]
*/
```
 
Eu apenas verifico se a raça do personagem é `terráqueo` e faço a operação `character.name.toUpperCase()`. Caso contrário, retorno os dados originais.
 
É possível fazer o mesmo com reduce:
 
```javascript
function callback(acumulado, atual) {
  if (atual.race === 'terráqueo') {
    acumulado.push({
      name: atual.name.toUpperCase(),
      race: atual.race
    })
  } else {
    acumulado.push({
      name: atual.name,
      race: atual.race
    })
  }
  
  return acumulado;
}

const initialValue = [];

const result = characters.reduce(callback, initialValue);
```
 
O resultado será exatamente o mesmo. Mas quais as diferenças?
 
- Primeiro, como o resultado será uma array, o `initialValue` é uma array vazia
- No começo da função callback, eu faço a mesma verificação de antes `atual.race === 'terráqueo'`. Mas agora em vez de retornar isso, eu faço um `.push()` para dentro da array com os resultados
- Por fim, retorno o `acumulado` para que a próxima iteração tenha esse valor para continuar incrementando
 
Como você pode ver, o map é muito mais simples. Sem contar que é possível aplicar um arrow function e early return para deixar mais simples ainda.
 
Assim como é possível mapear uma array com o reduce, também é possível filtrar.
 
### Reduce ou filter?
 
O filter é realmente um filtro, tipo o filtro de café.
 
**Ele filtra uma array e retorna uma lista apenas com os itens que atendem aos requisitos que você definiu.**
 
Veja mais detalhes nesse artigo de como [simplificar sua lógica com arrays com o método filter](https://demenezes.dev/posts/filter-javascript-array/).
 
Por exemplo, se você tiver uma array com dados de frutas, é possível filtrar e ficar apenas com a vermelhas:
 
```javascript
const fruits = [
  { name: 'Maçã',    color: 'Vermelha' },
  { name: 'Manga',   color: 'Amarela'  },
  { name: 'Banana',  color: 'Amarela'  },
  { name: 'Laranja', color: 'Laranja'  },
  { name: 'Uva',     color: 'Roxa'     },
  { name: 'Pera',    color: 'Amarela'  },
  { name: 'Morango', color: 'Vermelha' },
  { name: 'Abacaxi', color: 'Amarela'  },
  { name: 'Kiwi',    color: 'Verde'    },
  { name: 'Cereja',  color: 'Vermelha' }
];

const result = fruits.filter(function(fruit) {
  if (fruit.color === 'Vermelha') {
    return true;
  } else {
    return false;
  }
});

console.log(result);

/*
[
  { "name": "Maçã",    "color": "Vermelha" },
  { "name": "Morango", "color": "Vermelha" },
  { "name": "Cereja",  "color": "Vermelha" }
]
*/
```
 
Como previsto, o reduce pode fazer o mesmo:
 
```javascript
function callback(acumulado, atual) {
  if (atual.color === 'Vermelha') {
    acumulado.push(atual)
  }
  
  return acumulado;
}

const initialValue = [];

const result = fruits.reduce(callback, initialValue);
```
 
Como o reduce faz isso:
 
- Novamente existe o valor inicial com uma array vazia. Mesmo que o resultado contenha zero ou 1 item, a lógica é sempre começar com uma array esse tipo de desafio
- A função callback verifica se a fruta é da cor vermelha<ul><li>Se sim, insere ela no `acumulado` e retorna</li><li>Caso contrário, retorna o `acumulado` sem adicionar nada, isso acontece com as outras cores de frutas. Por isso a saída final tem menos itens que a array original</li></ul>
 
Os métodos map e filter sempre retornam uma array, então é fácil imaginar que o valor inicial é uma array vazia. Mas agora os exemplos são com métodos que não, necessariamente, retornam um array.
 
### Reduce ou find?
 
Esse método é o ["CTRL + F" do Javascript](https://demenezes.dev/posts/find-javascript-array/).
 
**O find encontra o primeiro item dentro de uma array que atende a um ou mais critérios e retorna esse item.**
 
Veja como ele faz isso, vou usar a mesma array de produtos de antes:
 
```javascript
const products = [
  { id: '1a2b3c4d', name: 'Camiseta Básica', color: 'Branca', size: 'M',     price: 200 },
  { id: '5e6f7g8h', name: 'Calça Jeans',     color: 'Azul',   size: 'L',     price: 500 },
  { id: '9i0j1k2l', name: 'Bolsa de Couro',  color: 'Marrom', size: 'Único', price: 800 },
  { id: '3m4n5o6p', name: 'Tênis Esportivo', color: 'Preto',  size: '42',    price: 300 },
  { id: '7q8r9s0t', name: 'Vestido Floral',  color: 'Rosa',   size: 'S',     price: 350 }
];

const result = products.find(function(product) {
  if (product.id === '3m4n5o6p') {
    return true;
  } else {
    return false;
  }
});

console.log(result);

/*
  {
    id: '3m4n5o6p',
    name: 'Tênis Esportivo',
    color: 'Preto',
    size: '42',
    weight: 300,
    availability: true
  }
*/
```
 
Ele encontra o primeiro que possui a propriedade `id` igual a `3m4n5o6p`. Após isso, ele finaliza a execução.
 
E como o reduce faria isso?
 
```javascript
function callback(resultado, atual) {
  if (atual.id === '3m4n5o6p') {
    return atual;
  } else {
    return resultado;
  }
}

const result = products.reduce(callback, null);
```
 
Algumas decisões que tomei:
 
- O valor inicial é `undefined`, isso porque se o produto não for encontrado, esse será o valor final
- Mudei o nome do parâmetro de `acumulado` para `resultado`, pois ela acumula dados a cada iteração
- Dentro da função callback, se o produto `atual` tiver o ID desejado, retorno ele, caso contrário retorno o `resultado`
- A execução só cairá no `if` uma vez (com o produto certo) e no `else` em todas as outras 
 
Veja mais uma versatilidade do reduce, retornar apenas um dos itens da array, e não uma array de itens.
 
### Reduce ou every?
 
Every em inglês: todo ou toda.
 
**O every responde (com `true` ou `false`) se todos os itens de uma array atendem aos requisitos**. Confira aqui no [artigo completo sobre every](https://demenezes.dev/posts/every-some-javascript-array/).
 
Vou usar uma array com dados de cidades para mostrar do que o every é capaz:
 
```javascript
const maioresCidadesBrasil = [
  { nome: 'São Paulo',      estado: 'SP', area: 1521   },
  { nome: 'Rio de Janeiro', estado: 'RJ', area: 1200   },
  { nome: 'Brasília',       estado: 'DF', area: 5800   },
  { nome: 'Salvador',       estado: 'BA', area: 706    },
  { nome: 'Fortaleza',      estado: 'CE', area: 314    },
  { nome: 'Belo Horizonte', estado: 'MG', area: 331    },
  { nome: 'Manaus',         estado: 'AM', area: 11400  },
  { nome: 'Curitiba',       estado: 'PR', area: 435    },
  { nome: 'Recife',         estado: 'PE', area: 218    },
  { nome: 'Porto Alegre',   estado: 'RS', area: 496    }
];

const result = maioresCidadesBrasil.every(function(cidade) {
  if (cidade.area > 300) {
    return true;
  } else {
    return false;
  }
});

console.log(result); // false
```
 
Esse exemplo mostra como verificar se todas as cidades de uma array possuem área maior que 300 mil km².
 
A resposta final é `false`. Mas se você trocar o `if (cidade.area > 300)` para `if (cidade.area > 200)` verá que o resultado muda para `true`.
 
Nesse momento o reduce diz "essa é muito fácil, manda outra mais difícil":
 
```javascript
function callback(acumulado, cidade) {
  const areaMaiorQue300 = cidade.area > 300;
  return acumulado && areaMaiorQue300;
}

const result = maioresCidadesBrasil.reduce(callback, true);
```
 
A estrutura aqui ficou um pouco diferente:
 
- O valor inicial é `true`, ou seja, eu parto do princípio que todas as cidades tem área acima de 300 mil km². Pois basta que uma cidade não tenha para o resultado final ser `false`
- Crio a `const areaMaiorQue300` que possui um valor booleano
- É na linha do `return` que está o segredo. Eu retorno uma operação lógica que tem dois valores booleanos separados por um `&amp;&amp;`. Se ambos os valores forem `true`, a resposta é `true`. Basta que um dos valores seja `false` para mudar o resultado até a última iteração
 
Se o reduce ficou mais simples que o outro método? Difícil responder.
 
### Reduce ou some?
 
Some em inglês: algum ou alguma.
 
**O [some](https://demenezes.dev/posts/every-some-javascript-array/) afirma se pelo menos um item de uma array atende aos requisitos**. Muito parecido com o every.
 
Vou pegar como exemplo a mesma array de cidades do every. O some pode responder perguntas como "entre as 10 maiores cidades do Brasil, existe alguma da Bahia (BA)?":
 
```javascript
const result = maioresCidadesBrasil.some(function(cidade) {
  if (cidade.estado === 'BA') {
    return true;
  } else {
    return false;
  }
});

console.log(result); // true
```
 
A versão "reduce" do some, é bem parecida com a do every:
 
```javascript
function callback(acumulado, cidade) {
  const cidadeDaBahia = cidade.estado === 'BA';
  return acumulado || cidadeDaBahia;
}

const result = maioresCidadesBrasil.reduce(callback, false);
```
 
Agora algumas coisas se invertem:
 
- Agora o valor inicial é `false`, pois basta que uma cidade atenda ao requisito para o resultado final ser `true`
- Na função callback, a `const cidadeDaBahia` também recebe um valor booleano que corresponde a essa afirmação
- O return também é bem parecido. A diferença é que a operação lógica vem com `||` e não `&amp;&amp;`
 
Essas foram as comparações do reduce com outros métodos comuns de array em Javascript.
 
Até agora, as funções callback dos exemplos receberam apenas dois parâmetros, `acumulado` e `atual`. Mas existem 4.
 
## Os 4 parâmetros da função callback
 
Os outros métodos que mencionei podem receber até 3 parâmetros.
 
Já no reduce, esse número pode chegar a 4. Assim como mostrei nos exemplos, você pode chamá-los como quiser, mas sempre adapte a cada cenário.
 
Veja agora os parâmetros.
 
### O parâmetro "acumulado"
 
Esse parâmetro depende do valor inicial apenas na primeira iteração.
 
Sem o valor inicial, `acumulado` é o **primeiro** item da array. No exemplo abaixo, o valor desse parâmetro é `76`:
 
```javascript
const numbers = [ 76, 23, 89, 54 ];

const result = numbers.reduce(function(acumulado, atual) {
  // ...
});
```
 
Com o valor inicial, `acumulado` é esse valor. No exemplo abaixo, o valor é `8`:
 
```javascript
const numbers = [ 76, 23, 89, 54 ];

function callback(acumulado, atual) {
  // ...
}

const initialValue = 8;

const result = numbers.reduce(callback, initialValue);
```
 
Da segunda iteração em diante, ele sempre será o retorno da iteração anterior.
 
### O parâmetro "atual"
 
Esse parâmetro também depende do valor inicial.
 
Sem esse valor, `atual` é o **segundo** item da array, `23`:
 
```javascript
const numbers = [ 76, 23, 89, 54 ];

const result = numbers.reduce(function(acumulado, atual) {
  // ...
});
```
 
Com o valor inicial, `atual` passa a ser o **primeiro** item da array, `76`:
 
```javascript
const numbers = [ 76, 23, 89, 54 ];

function callback(acumulado, atual) {
  // ...
}

const initialValue = 8;

const result = numbers.reduce(callback, initialValue);
```
 
Da segunda iteração em diante, ele sempre será o próximo item da array.
 
### O parâmetro "index"
 
Essa é fácil: ele é um número.
 
Na primeira iteração, é 0...
 
Na segunda iteração, é 1...
 
Na terceira iteração, é 2...
 
Na quarta iteração, é 3... é isso:
 
```javascript
const numbers = [ 76, 23, 89, 54 ];

function callback(acumulado, atual, index) {
  console.log(index);
}

const initialValue = 8;

const result = numbers.reduce(callback, initialValue);

/*
  0
  1
  2
  3
*/
```
 
MAS ALTO LÁ!
 
**Se você não fornecer um valor inicial, não existirá o index 0, e começará diretamente no index 1**. Isso acontece porque, como falei lá no começo, sem o valor inicial acontece uma iteração a menos:
 
```javascript
const numbers = [ 76, 23, 89, 54 ];

function callback(acumulado, atual, index) {
  console.log(index);
}

const result = numbers.reduce(callback);

/*
  1
  2
  3
*/
```
 
Você pode usar o parâmetro index para auxiliar em muitos desafios do dia a dia.
 
Acesse os posts que linkei sobre outros métodos de array. Lá você encontrará diversos exemplo de como usar o parâmetro index.
 
### O parâmetro "array"
 
Esse é o único parâmetro que não muda de valor.
 
**Ele sempre representa a array que você está iterando**. Não recomendo usar esse parâmetro para alterar a array enquanto executa o reduce nela. Apenas faça consultas para outras operações.
 
Além dos exemplos com o index, nos outros posts você também encontrará desafios com o parâmetro array.
 
---
 
Se você já leu os outros posts dessa série, sabe o que eu sempre digo. Não basta entender o método apenas na teoria, você precisa saber quando aplicar.
 
## Como saber o momento de usar o reduce?
 
Essa é uma pergunta bem complicada.
 
Se você leu tudo até agora, primeiramente parabéns. Segundamente, você percebeu que o reduce é um método bastante genérico. Isso porque além de poder substituir outros métodos (map, filter, find, every e some), ele também pode retornar qualquer tipo de dado.
 
E essa amplitude torna a resposta muito difícil, mas arrisco dizer que para usar o reduce você precisa de 3 coisas.
 
### Você precisa de um dado
 
Precisar de um dado é algo raro na programação (ironia).
 
Esse dado pode ser string, number, booleano, objeto ou até outra array.
 
Mas, já que você precisa manipular dados a todo momento, como saber se deve usar o reduce ou outro método?
 
### Nenhum outro método de array dá conta do problema
 
Daí sobrou apenas o reduce.
 
Na minha opinião, quando nenhum outro método de array em Javascript dá conta de gerar esse dado para você, use o reduce.
 
Ao longo desse post você viu como resolver o mesmo desafio com reduce ou outros métodos. Esses são exemplos onde você **não** precisa usar o reduce.
 
Por outro lado, lembra do exemplo de somar o valor total dos produtos em um ecommerce? Esse desafio exige o uso do reduce. Existem outras formas como usar uma iteração com `for`, mas prefiro a programação funcional.
 
Porém, existem casos onde ***depende***. Lembra daquele exemplo da array de produtos? E se você precisar dizer se todos os produtos da array possuem preço acima de R$ 300?
 
Você pode simplesmente:
 
- Usar o reduce
- Definir o valor inicial como `true`
- E retornar `acumulado &amp;&amp;` um valor booleano que diz se o produto possui preço acima de R$ 300
 
```javascript
const products = [
  { id: '1a2b3c4d', name: 'Camiseta Básica', color: 'Branca', size: 'M',     price: 200 },
  { id: '5e6f7g8h', name: 'Calça Jeans',     color: 'Azul',   size: 'L',     price: 500 },
  { id: '9i0j1k2l', name: 'Bolsa de Couro',  color: 'Marrom', size: 'Único', price: 800 },
  { id: '3m4n5o6p', name: 'Tênis Esportivo', color: 'Preto',  size: '42',    price: 300 },
  { id: '7q8r9s0t', name: 'Vestido Floral',  color: 'Rosa',   size: 'S',     price: 350 }
];

function callback(acumulado, produtoAtual) {
  const produtoAtualAcima300 = produtoAtual.price > 300;
  return acumulado && produtoAtualAcima300;
}

const initialValue = true;
const result = products.reduce(callback, initialValue);
console.log(result); // false
```
 
Mas se o reduce for muito complicado, você pode concatenar um map com um every:
 
- O map irá converter a array de produtos em uma array que contém apenas os preços dos produtos
- O every vai verificar se essa array contém apenas números acima de 300
 
```javascript
const result = products
  .map(produto => produto.price)
  .every(price => price > 300);

console.log(result); // false
```
 
Do meu ponto de vista, a lógica é mais fácil de entender, mas exige duas iterações. Já o reduce é mais complicadinho, mas itera uma vez só. Tudo depende.
 
### Você tem uma array em mãos
 
O último critério para saber se você precisa do reduce é ter uma array.
 
Isso porque o reduce é um método de array. Não é possível executar ele a partir de uma string, número, booleano ou objeto, a menos que você converta isso para uma array antes.
 
## Callback
 
Quanta coisa ein...
 
Recapitulando, o reduce é um método de array em Javascript que reduz uma array a apenas um valor, converte em outra array, manipula, e pode retornar qualquer tipo de dado.
 
O primeiro parâmetro do reduce é uma função callback que pode receber até 4 parâmetros:
 
- O valor acumulado das últimas iterações
- O item atual da array
- O index
- E a própria array que você está iterando
 
O segundo parâmetro do reduce é o valor inicial das iterações. Esse é o valor do primeiro parâmetro da função callback na primeira iteração. Se você não informar ele (mas recomendo que sempre faça isso), haverá uma iteração a menos.
 
Até a penúltima iteração, o retorno da função callback do reduce define qual será o valor do parâmetro `acumulado` na próxima. Na última, o retorno da função callback é o próprio return do reduce.
 
O reduce é um método tão flexível, que pode substituir outros métodos de array em Javascript, como:
 
- map
- filter
- find
- every
- some
 
Saber o momento certo de usar o reduce pode ser um pouco complicado. Mas posso dizer que é quando:
 
- Você precisa de um dado
- Nenhum outro método Javascript é capaz de gerar esse dado
- Esse dado vem de uma array
 
Se é possível suar ao escrever um texto tão denso e com um tópico tão difícil de explicar, então eu suei escrevendo esse texto haha.
 
O reduce é um método que exige conhecimento de vários outros tópicos em Javascript para compreender bem. Então se algo ficou complicado, volte aqui depois de um tempo, garanto que você irá perceber coisas novas.
 
Esse é o último post de uma série de 6 artigos sobre métodos de array em Javascript. Linkei todos os outros 5 foram aqui em algum momento do texto.
 
Obrigado pela sua leitura. Deixe um comentário se ficou com dúvidas.
 
Se esse artigo te ajudou de alguma forma, e ficou com vontade de dizer um **obrigado**, compartilhe com um amigo ou nas redes sociais.
 
Até a próxima!