Article image
Michel Souza
Michel Souza17/08/2023 13:11
Compartilhe

Funções em JavaScript: Definição e Aplicação da Função de Alta Ordem Map em um Cenário Prático

  • #JavaScript

Salve, família!!!

Por qual motivo é uma boa prática utilizar funções de alta ordem, como por exemplo a função Map, durante o processo de desenvolvimento de um software?

Falando nisso, o que seria uma função de alta ordem?

Este conceito é muito utilizado no paradigma de programação funcional e iremos aplicá-lo de forma prática neste artigo, utilizando a poderosa linguagem JavaScript.

Teremos a seguinte caminhada:  

  1. Introdução
  2. Conceitos Básicos
  3. Cenários Práticos
  4. Conclusão
  5. Referências

Para desenvolvimento dos códigos demonstrados foi utilizado o ambiente de execução server-side Node.js e a ferramenta de edição Visual Studio Code.

1. Introdução

A linguagem JavaScript originalmente foi projetada baseada em eventos, porém atualmente ela é multi-paradigma e apresenta uma imensa versatilidade. Neste contexto, torna-se fundamental utilizar uma abordagem funcional para melhoria da qualidade e manutenção de programas, devido às características apresentadas neste paradigma.

Com a utilização de conceitos como clausura, funções de alta ordem, composição e encapsulamento de funções, dentre outros, este paradigma possibilita otimização, paralelismo e diminuição de efeitos colaterais em códigos.

Dentre estes conceitos, vamos nos atentar às Funções de Alta Ordem, especificamente a função Map, aplicado em um cenário prático fictício, que será discutido durante a apresentação do artigo.

2. Conceitos Básicos

Inicialmente é sempre importante apresentar alguns conceitos, para melhor entendimento dos problemas propostos.

2.1 Funções em Programação

As funções são módulos de código independentes que realizam uma tarefa específica. Geralmente elas recebem dados, realizam algum tipo de processamento e retornam um resultado na saída (esse último nem sempre é obrigatório).

Depois que uma função é programada, ela pode ser usada repetidamente, sendo invocada em outras partes do programa, inclusive dentro de funções.

2.2 Funções de Primeira Ordem e Arrow Function Expression

Em JavaScript, assim como em outras linguagens de programação, as funções são tratadas como qualquer outra variável. Este é o conceito de Função de Primeira Ordem ou First-class Function, que é uma das marcas da versatilidade dessa linguagem.

(Fonte: Documentação MDN - First-class Function)

Outra ferramenta da linguagem, a Arrow Function Expression, é uma alternativa compacta para definir uma função, sem utilizar a declaração tradicional.

(Fonte: Documentação MDN - Arrow Function Expression)

2.3 Aplicação dos Conceitos

Abaixo está sendo apresentado um exemplo prático de uma calculadora básica, aplicando estes conceitos:

//Função de Primeira Ordem
const calcular = function (numero1,numero2,operacao) {
return `Resultado: ${operacao(numero1,numero2)}`
}

Observação: a função calcular tem como parâmetros dois números e outra função, que realizará uma operação aritmética relacionada.

//Arrow Function Expression
const soma = (a,b) => a + b;
const subtracao = (a,b) => a - b;
const multiplicacao = (a,b) => a * b;
const divisao = (a,b) => a / b

Observação: as funções soma, subtracao, multiplicacao e divisao, são definidas utilizando arrow function.

//Verificação dos Resultados
console.log(calcular(1,2,soma));
console.log(calcular(9,7,subtracao));
console.log(calcular(4,3,multiplicacao));
console.log(calcular(18,9,divisao))

Saída:

Resultado: 3
Resultado: 2
Resultado: 12
Resultado: 2

Ambas as técnicas são utilizadas na implementação de Funções de Alta Ordem ou Higher-order Function (HOF), como a Map, objetivo de nosso estudo.

2.4 Map e Funções de Alta Ordem

Uma função de ordem superior é uma função que recebe outras funções como parâmetros ou então retorna uma função.

A função map() é utilizada em JavaScript como um método aplicado em instâncias de objetos do tipo Array. Ele recebe como parâmetro uma função definida anteriormente ou no momento da invocação do método. O retorno é um array preenchido com os resultados da aplicação da função passada em cada elemento da array de chamada.

Segue trecho de código contendo um exemplo simples de utilização do map(), definindo uma arrow function para realizar a transformação:

//Criando um array de base
const baseArray = [20.1, 0.56, 1.7, 4.2, 0.7, 6.3];

// Definindo uma arrow function para Map
const funcMap = x => x * 60.0;

//Aplicando Map para criação de novo array
const newArray = baseArray.map(funcMap);

//Verificação dos Resultados
console.log(newArray);

Saída:

[ 1206, 33.6, 102, 252, 42, 378 ]

Diagrama do funcionamento, para facilitar o entendimento da aplicação da função:

image

(Fonte: Autor)

Os trechos abaixo realizam a mesma operação, aplicando técnicas diferentes de atribuição de funções.

  • Alternativa 1: Utilizando arrow function no momento da invocação do método:
const newArray1 = baseArray.map(x => x * 60.0);
console.log(newArray1);

Saída: 

[ 1206, 33.6, 102, 252, 42, 378 ]
  • Alternativa 2: Definindo uma função de primeira ordem e passando como parâmetro para o map():
function funcMap2(x) {
return x * 60.0;
}
const newArray2 = baseArray.map(funcMap2);
console.log(newArray2);

Saída: 

[ 1206, 33.6, 102, 252, 42, 378 ]
  • Alternativa 3: Utilizando arrow function nomeada no momento da invocação do método:
const newArray3 = baseArray.map(funcMap3 = x => x * 60.0);
console.log(newArray3);

Saída: 

[ 1206, 33.6, 102, 252, 42, 378 ]
  • Alternativa 4: Utilizando o conceito de função anônima, no momento da invocação do método:
const newArray4 = baseArray.map(function (x){
return x * 60.0
});

Saída: 

[ 1206, 33.6, 102, 252, 42, 378 ]

3. Cenários Práticos

Agora, vamos montar o seguinte enredo: uma loja especializada em serviços de manutenção em equipamentos de informática, a TechDIO. A partir dela, vamos montar três pequenos cenários onde será aplicada a função map().

3.1 Cenário: Orçamento de Serviços

Todo orçamento da TechDIO é gerado inicialmente pelo setor técnico, onde são somados os valores das peças que precisam ser trocadas e as horas empenhadas na execução dos serviços, calculando um valor total. Em seguida, este orçamento é encaminhado para o setor de gestão que aplica as taxas de impostos cobradas, além de arredondar os valores para cima. Como isso pode ser realizado através de um sistema computacional?

No código abaixo, está sendo aplicada a função map() para gerar um valor final de todos os orçamentos, a partir do array de orçamentos técnicos:

/*Aplicação da Função Map - Cenário 1*/
const orcamentosTecnicos = [200.0,300.0,550.0,200.0,930.00]
const orcamentosFinais = orcamentosTecnicos.map(function (x){
let tax = 0.17
return x * (1+tax)
})
.map(x => Math.ceil(x))
console.log(orcamentosFinais);

Saída:

[ 234, 351, 644, 234, 1089 ]

Observe que neste exemplo foram usados maps em cadeia. É possível realizar um pipeline de transformações utilizando esta função. Outra observação é que aplicamos uma função anônima como parâmetro para o map().

3.2 Cenário: Horas de Indisponibilidade

Além de manutenção, a TechDIO possui um cliente específico que contratou serviço de empréstimo de equipamentos, como CPU, impressoras e monitores.

Uma das cláusulas do contrato define um tempo máximo mensal, que o equipamento pode ficar fora de operação ou indisponível. Este indicador é apresentado no contrato em minutos, porém o sistema de gerenciamento está salvo em horas.

No código abaixo, está sendo apresentada a estrutura de dados que salva as informações e representa cada dispositivo:

/*Aplicação da Função Map - Cenário 2*/
const dispositivos = [
{id: "IMP0027", tipo: "Impressora", operacional: true, horasIndisponivel: 20.1},
{id: "MNT0301", tipo: "Monitor", operacional: true, horasIndisponivel: 0.56},
{id: "CPU0004", tipo: "CPU", operacional: false, horasIndisponivel: 1.7},
{id: "CPU0002", tipo: "CPU", operacional: true, horasIndisponivel: 4.2},
{id: "IMP1049", tipo: "Impressora", operacional: false, horasIndisponivel: 0.7},
{id: "MNT0022", tipo: "Monitor", operacional: false, horasIndisponivel: 6.3}
]

Agora, a aplicação do map() para emitir informações de indisponibilidade em minutos:

const mapHorasMin = x => x.horasIndisponivel * 60.0
const minIndisponivel = dispositivos.map(mapHorasMin)
console.log(minIndisponivel)

Saída:

[ 1206, 33.6, 102, 252, 42, 378 ]

Observe que se trata do mesmo exemplo apresentado para definir a função map() anteriormente, porém aplicado em um contexto prático.

Vale ressaltar que poderiam ser aplicadas outras funções de alta ordem como filter(), para verificar quais equipamentos ultrapassaram o tempo de indisponibilidade contratual ou o reduce() para indicar os valores máximos e mínimos.

3.3 Cenário: Satisfação do Cliente

No último problema, existe o seguinte contexto: o setor de qualidade da TechDIO possui um formulário de satisfação, onde recebe uma nota final de 0 a 100%, a partir das respostas dos clientes. Eles necessitam implementar um indicador tipo NPS e armazenar essas informações,  onde o cliente é promotor se a média das notas é maior que 80, neutro se a média estiver entre 50 e 80, e detrator se for igual ou abaixo de 50. 

No trecho de código abaixo, é gerado um array de notas de aleatórias de 20 clientes:

/*Aplicação da Função Map - Cenário 3*/
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

const clienteNotas = [];
for (let i = 0 ; i < 20 ; i++){
clienteNotas.push(getRandom(0,100));
}
console.log(clienteNotas);

Saída:

[
62, 84, 41, 12, 68,
2, 69, 47, 55, 73,
89, 26, 67, 4, 95,
54, 68, 41, 81, 63
]

No trecho final, é gerado um array com os indicadores NPS, aplicando map() chamando uma função anônima com uma estrutura condicional if/else if/else:

const clienteNPS = clienteNotas.map(
function(x){
    if (x > 80) {
      return "Promotor"
    } else if (x > 50){
      return "Neutro"
    } else {
      return "Detrator"
    }
});
console.log(clienteNPS);

Saída:

[
'Neutro', 'Promotor', 'Detrator', 'Detrator', 'Neutro',
'Detrator', 'Neutro', 'Detrator', 'Neutro', 'Neutro',
'Promotor', 'Detrator', 'Neutro', 'Detrator', 'Promotor', 
'Neutro', 'Neutro', 'Detrator', 'Promotor', 'Neutro'
]

4. Conclusão

Por meio deste artigo foi possível percorrer alguns conceitos relacionado a programação funcional, utilizando a poderosa e versátil linguagem JavaScript.

Foram apresentados vários exemplos de utilização da função de alta ordem Map, onde foi verificada a grande versatilidade mencionada anteriormente.

O uso de um cenário, mesmo que pequeno e fictício, colaborou para exposição dos trechos de códigos com implementações básicas e intermediárias.

Vale ressaltar que os conceitos foram apresentados de forma resumida. Fica como sugestão a pesquisa mais profunda da definição e aplicação do paradigma funcional, bem como a documentação técnica do JavaScrpit, MDN Web Docs.

5. Referências

[1] https://users.cs.utah.edu/~germain/PPS/Topics/functions.html

[2] https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function

[3] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

[4] https://kotlinlang.org/docs/lambdas.html

[5] https://developer.mozilla.org/en-US/docs/Web/JavaScript

Compartilhe
Comentários (1)
Laísa Sousa
Laísa Sousa - 24/08/2023 21:27

Muito bom!!!