C# - Map : Conceito e Uso


Hoje veremos o conceito de Map e como usar esse conceito na linguagem C#.

Segundo a Wikipédia, map é o nome de uma função de ordem superior que aplica uma determinada função a cada elemento de um functor, por exemplo uma lista, contêiner sequenciais, etc., retornando uma lista de resultados na mesma ordem.

Suponha que temos uma lista de inteiros {1,2,3,4,5} e gostaríamos de calcular o quadrado de cada inteiro. Para fazer isso definimos uma função para elevar cada número ao quadrado:  quadrado x = x * x

Feito isso podemos usar o map e aplicar a função a cada elemento da lista:   map quadrado {1,2,3,4,5}

O resultado seria uma nova lista contendo os valores : { 1, 4, 9, 16, 25 }

Esse é o conceito de map e é assim que ele funciona.

Então, simplificando podemos dizer que :  "A operação map atua em uma sequência de itens, aplica alguma transformação a cada um desses itens e retorna uma nova sequência com os itens resultantes."

Na linguagem C# não temos um recurso pronto semelhante ao conceito de Map, mas podemos simular isso usando o LINQ como eu mostrei neste artigo : LINQ - Usando Map, Reduce e Filter

Assim podemos ter o seguinte código:

        using System;
        using System.Linq;
        static void Main(string[] args)
        {
            int[] numeros = { 2, 3, 4, 5 };
            var elevarAoQuadrado = numeros.Select(x => x * x);

            Console.WriteLine(string.Join(" ", elevarAoQuadrado));
            Console.ReadLine();
        }

Aqui elevarAoQuadrado vai retornar uma sequência com o resultado da operação onde cada elemento de números será multiplicado por ele mesmo.

O operador Select itera em cada elemento, e, para cada um deles aplica o método que passamos como um parâmetro via instrução lambda, isso nos poupa de usar o foreach, e , além disso, é mais elegante. 

Neste caso, passamos o método como uma expressão lambda x => x * x, onde x é cada elemento da matriz passada como um parâmetro da expressão, e x * x é o corpo do método, assim poderemos transformar os elementos da matriz sem criar nenhum laço.

Assim o Select retorna uma coleção do mesmo tamanho que a coleção à qual aplicamos a transformação.

Agora, se você não puder ou não quiser usar o LINQ, então vai ter que fazer isso 'no braço' usando código C#:

        using static System.Console;
        using System.Collections.Generic;

        static List<int> ElevarAoQuadrado(List<int> lista)
        {
            var resultado = new List<int>();
            foreach (var x in lista)
                resultado.Add(x * x);
            return resultado.ToList();
        }

        static void Main(string[] args)
        {
            var numeros = new List<int> { 1, 2, 3, 4, 5 };
            var resultado = ElevarAoQuadrado(numeros);
            foreach (var n in resultado)
                Write(n + " ");
            ReadLine();
        }

Observe que temos que gerar a lista com os resultados obtidos pois é assim que o Map funciona.

Se você puder usar a linguagem F# pode expressar isso assim:

let resultado = seq.map (fun x -> x * x) numeros

Aqui estamos assumindo que numeros é uma sequência de números inteiros que já foi declarada e a seguir usamos a função map no módulo Seq passando a sequência como parâmetro juntamente com uma função que pega um elemento da sequência e o multiplica por ele mesmo.

Nota: A palavra-chave fun é usada para definir uma expressão lambda, ou seja, uma função anônima.

E estamos conversados.

"Porque pela graça sois salvos, por meio da fé; e isto não vem de vós, é dom de Deus.
Não vem das obras, para que ninguém se glorie;"
Efésios 2:8,9

Referências:


José Carlos Macoratti