Filtro (função de ordem superior) - Filter (higher-order function)

Na programação funcional , o filtro é uma função de ordem superior que processa uma estrutura de dados (geralmente uma lista ) em alguma ordem para produzir uma nova estrutura de dados contendo exatamente aqueles elementos da estrutura de dados original para os quais um determinado predicado retorna o valor booleano true .

Exemplo

Em Haskell , o exemplo de código

 filter even [1..10]

avalia a lista 2, 4,…, 10 aplicando o predicado evena cada elemento da lista de inteiros 1, 2,…, 10 nessa ordem e criando uma nova lista daqueles elementos para os quais o predicado retorna o valor booleano verdadeiro , fornecendo assim uma lista contendo apenas os membros pares dessa lista. Por outro lado, o exemplo de código

 filter (not . even) [1..10]

avalia para a lista 1, 3,…, 9 coletando aqueles elementos da lista de inteiros 1, 2,…, 10 para os quais o predicado evenretorna o valor booleano falso ( .sendo o operador de composição da função ).

Exemplo visual

Abaixo, você pode ver uma visão de cada etapa do processo de filtro para uma lista de inteiros de X = [0, 5, 8, 3, 2, 1]acordo com a função:

Esta função expressa que se for par, o valor de retorno é , caso contrário, é . Este é o predicado.

aplicando etapas de processamento da função de filtro
Visualização das etapas de processamento ao aplicar a função de filtro em uma lista

Comparação de linguagem

Filtro é uma função padrão para muitas linguagens de programação , por exemplo, Haskell, OCaml , Standard ML ou Erlang . Common Lisp fornece as funções remove-ife remove-if-not. Scheme Requests for Implementation (SRFI) 1 fornece uma implementação de filtro para a linguagem Scheme . C ++ fornece os algoritmos remove_if (com mutação) e remove_copy_if(sem mutação); C ++ 11 fornece adicionalmente copy_if(sem mutação). Smalltalk fornece o select:método para coleções. O filtro também pode ser realizado usando compreensões de lista em idiomas que as suportam.

Em Haskell, filterpode ser implementado assim:

 filter :: (a -> Bool) -> [a] -> [a]
 filter _ []     = []
 filter p (x:xs) = [x | p x] ++ filter p xs

Aqui, []denota a lista vazia, ++a operação de concatenação de lista e [x | p x]denota uma lista contendo um valor xcondicionalmente p x,, se a condição for mantida (avalia para True).

Filtro em vários idiomas
Língua Filtro Notas
APL (pred array)/array
ou
pred{⍵/⍨⍺⍺ ⍵}array
O segundo exemplo é um APL dop .
C # 3.0 ienum.Where(pred)
ou
a wherecláusula
Onde está um método de extensão
ienum é um IEnumerable
Da mesma forma em todas as linguagens .NET
CFML obj.filter(func) Onde objestá um array ou uma estrutura. O funcrecebe como argumento o valor de cada elemento.
Clojure (filter predicate list) Ou, por meio da compreensão de lista :(for [x list :when (pred x)] x)
Lisp Comum (remove-if inverted-pred list)
(remove-if (complement pred) list)
(remove-if-not pred list)
A função remove-if-notfoi substituída em favor da equivalente remove-ifonde o predicado é complementado. Assim, o filtro (remove-if-not #'oddp '(0 1 2 3))deve ser escrito (remove-if (complement #'oddp) '(0 1 2 3))ou mais simples: (remove-if #'evenp '(0 1 2 3))onde evenpretorna o valor invertido de oddp.
C ++ std::remove_copy_if(begin, end, result, prednot)
std::copy_if(begin, end, result, pred) (C++11)
no cabeçalho <algorithm>
começo , fim , resultado são iteradores o
predicado é revertido
D std.algorithm.filter!(pred)(list)
Erlang lists:filter(Fun, List) Ou, por meio da compreensão de lista :[ X || X <- List, Fun(X) ]
Groovy list.findAll(pred)
Haskell filter pred list Ou, por meio da compreensão de lista :[x | x <- list, pred x]
Haxe list.filter(pred)
Lambda.filter(list, pred)
Ou, por meio da compreensão de lista :[x | x <- list, pred x]
J (#~ pred) list Um exemplo de gancho monádico. # é copiar, ~ inverte argumentos.(f g) y = y f (g y)
Julia filter(pred, array) A função de filtro também aceita dicttipo de dados. Ou, por meio da compreensão de lista :[x for x in array if pred(x)]
Java 8+ stream.filter(pred)
JavaScript 1.6 array.filter(pred)
Kotlin array.filter(pred)
Mathematica Select[list, pred]
Objective-C ( Cocoa no Mac OS X 10.4+) [array filteredArrayUsingPredicate:pred] predé um objeto NSPredicate , que pode ser limitado em expressividade
F # , OCaml , ML padrão List.filter pred list
PARI / GP select(expr, list) A ordem dos argumentos é invertida no v. 2.4.2.
Perl grep block list
grep expr, list
PHP array_filter(array, pred)
Prolog filter(+Closure,+List,-List) Desde ISO / IEC 13211-1: 1995 / Cor.2: 2012, o padrão principal contém aplicação de fechamento via call/N
Pitão filter(func, list) Ou, via compreensão da lista : . No Python 3, foi alterado para retornar um iterador em vez de uma lista. A funcionalidade complementar, retornando um iterador sobre os elementos para os quais o predicado é falso, também está disponível na biblioteca padrão como no módulo. [x for x in list if pred(x)]filterfilterfalseitertools
Rubi enum.find_all {block}
enum.select {block}
enum é uma enumeração
Ferrugem iterator.filter(pred) iteratoré um Iteratore o filtermétodo retorna um novo iterador; predé uma função (especificamente FnMut) que recebe o item do iterador e retorna umbool
S , R Filter(pred,array)
array[pred(array)]
No segundo caso, pred deve ser uma função vetorizada
Scala list.filter(pred) Ou, via para compreensão: for(x <- list; if pred) yield x
Esquema R 6 RS (filter pred list)
(remove inverted pred list)
(partition pred list list)
Conversa fiada aCollection select: aBlock
Rápido array.filter(pred)
filter(sequence, pred)
XPath , XQuery list[block]
filter(list, func)
No blockitem de contexto .contém o valor atual

Variantes

O filtro cria seu resultado sem modificar a lista original. Muitas linguagens de programação também fornecem variantes que modificam destrutivamente o argumento da lista para um desempenho mais rápido. Outras variantes de filtro (por exemplo, Haskell dropWhilee partition) também são comuns. Uma otimização de memória comum para linguagens de programação puramente funcionais é fazer com que a lista de entrada e o resultado filtrado compartilhem a cauda comum mais longa ( compartilhamento de cauda ).

Veja também

Referências