Programação funcional no jQuery
Depois de muito tempo sem aparecer por aqui, volto para falar sobre um assunto que tenho tido muito interesse ultimamente: Javascript.
Javascript sempre foi uma linguagem abominada por muita gente, mas que há algum tempo tem recebido mais atenção. Na minha opinião, grande parte da evolução da linguagem se deve à criação de bibliotecas que simplificam (e muito!) as tarefas mais comuns no dia-a-dia do programador. Dentre estas bibliotecas, a minha favorita é a jQuery.
Comecei a usar jQuery na versão 1.2.6. De lá pra cá (a versão atual é a 1.4.2), muita coisa melhorou! A documentação está excelente, a existem ferramentas desenvolvidas por terceiros que são uma mão na roda!
Como Python é minha linguagem preferida, muitas vezes sinto falta de algumas funcionalidades dela quando estou programando em Javascript/jQuery. Recentemente descobri equivalentes às funções map e filter, para manipulação de listas, no jQuery.
A primeira opção é usar a jQuery.map(), cuja utilização é bem direta:
var resultado = jQuery.map([1, 2, 3, 4, 5], function(valor, i) {
return valor * valor;
});
O primeiro argumento é a lista (o array) e o segundo é a função (lambda) que será aplicada a cada item da lista. O retorno é uma nova lista: [1, 4, 9, 16, 25].
Infelizmente, não existe a função jQuery.filter(), mas a jQuery.map() pode ser usada em substituição, bastando que para isso se retorne null para os valores que deseja filtrar:
var resultado = jQuery.map([1, 2, 3, 4, 5], function(valor, i) {
return valor % 2 == 0 ? valor : null;
});
O retorno neste caso é: [2, 4].
A segunda opção eu acabei descobrindo por acaso. É possível usar as funções .map() e .filter(), originalmente utilizadas para manipulação de objetos jQuery, para manipular listas:
var resultado = $([1, 2, 3, 4, 5]).map(function(i, valor) {
return valor * valor;
}).get();
var resultado = $([1, 2, 3, 4, 5]).map(function(i, valor) {
return valor % 2 == 0;
}).get();
Note que neste caso a ordem dos argumentos da função lambda é o inverso do primeiro caso. Como essa última utilização não é tão direta, cabem algumas explicações.
Ao passar um array para a função jQuery (abreviada por $), é possível usar as funções .map() e .filter(), exatamente como você faria para elementos DOM. Como o resultado dessas funções é um objeto jQuery, é necessário usar a função .get(), para transformá-lo novamente em um array Javascript.
Para ajudar na compreensão, escrevi um exemplo funcional, com testes unitários feitos com o framework QUnit.