Qual é exatamente a diferença entre array_map
, array_walk
e array_filter
. O que pude ver na documentação é que você pode transmitir uma função de retorno de chamada para executar uma ação na matriz fornecida. Mas não pareço encontrar nenhuma diferença em particular entre eles.
Eles executam a mesma coisa?
Eles podem ser usados de forma intercambiável?
Agradeço sua ajuda com exemplos ilustrativos, caso sejam diferentes.
Respostas:
array_map
não pode alterar os valores dentro da (s) matriz (s) de entrada enquantoarray_walk
pode; em particular,array_map
nunca muda seus argumentos.array_map
não pode operar com as teclas da matriz,array_walk
pode.array_map
retorna uma nova matriz,array_walk
somente retornatrue
. Portanto, se você não deseja criar uma matriz como resultado de atravessar uma matriz, deve usararray_walk
.array_map
também pode receber um número arbitrário de matrizes e pode iterar sobre elas em paralelo, enquantoarray_walk
opera apenas em uma.array_walk
pode receber um parâmetro arbitrário extra para passar para o retorno de chamada. Isso é irrelevante desde o PHP 5.3 (quando funções anônimas foram introduzidas).array_map
tem o mesmo comprimento que a da maior matriz de entrada;array_walk
não retorna uma matriz, mas ao mesmo tempo não pode alterar o número de elementos da matriz original;array_filter
seleciona apenas um subconjunto dos elementos da matriz de acordo com uma função de filtragem. Ele preserva as chaves.Exemplo:
Resultado:
fonte
array_map(callback($key, $value), array_keys($array), $array)
A idéia de mapear uma função para a matriz de dados vem da programação funcional. Você não deve pensar em
array_map
umforeach
loop que chama uma função em cada elemento da matriz (mesmo que seja assim que é implementado). Deve-se considerar a aplicação da função a cada elemento da matriz independentemente.Em teoria, coisas como mapeamento de funções podem ser feitas em paralelo, pois a função aplicada aos dados deve afetar APENAS os dados e NÃO o estado global. Isso ocorre porque é
array_map
possível escolher qualquer ordem na qual aplicar a função aos itens (embora isso não ocorra no PHP).array_walk
por outro lado, é a abordagem exatamente oposta ao tratamento de matrizes de dados. Em vez de manipular cada item separadamente, ele usa um estado (&$userdata
) e pode editar o item no local (como um loop foreach). Como cada vez que um item é$funcname
aplicado a ele, ele pode alterar o estado global do programa e, portanto, requer uma única maneira correta de processar os itens.De volta ao PHP,
array_map
earray_walk
são quase idênticos, excetoarray_walk
dão a você mais controle sobre a iteração de dados e são normalmente usados para "alterar" os dados no local versus retornar um novo array "alterado".array_filter
é realmente uma aplicação dearray_walk
(ouarray_reduce
) e é mais ou menos fornecida apenas por conveniência.fonte
array_filter()
pode ser implementado usandoarray_walk()
?A partir da documentação,
array_walk pega uma matriz e uma função
F
e a modifica substituindo cada elemento x porF(x)
.array_map faz exatamente a mesma coisa, exceto que, em vez de modificar no local, ele retornará uma nova matriz com os elementos transformados.
array_filter com função
F
, em vez de transformar os elementos, removerá qualquer elemento queF(x)
não seja verdadeirofonte
array_walk
retornasse uma matrizarray_map
e imaginei que o problema estava em minha função. Não percebi até que vi que o tipo de retorno é booleano.As outras respostas demonstram a diferença entre array_walk (modificação no local) e array_map (retornar cópia modificada) muito bem. No entanto, eles realmente não mencionam array_reduce, que é uma maneira esclarecedora de entender array_map e array_filter.
A função array_reduce pega uma matriz, uma função de dois argumentos e um 'acumulador', assim:
Os elementos da matriz são combinados com o acumulador, um de cada vez, usando a função fornecida. O resultado da chamada acima é o mesmo que fazer isso:
Se você preferir pensar em termos de loops, é como fazer o seguinte (na verdade, usei isso como um fallback quando array_reduce não estava disponível):
Esta versão em loop deixa claro por que chamei o terceiro argumento de 'acumulador': podemos usá-lo para acumular resultados a cada iteração.
Então, o que isso tem a ver com array_map e array_filter? Acontece que ambos são um tipo específico de array_reduce. Podemos implementá-los assim:
Ignore o fato de que array_map e array_filter recebem seus argumentos em uma ordem diferente; isso é apenas outra peculiaridade do PHP. O ponto importante é que o lado direito é idêntico, exceto pelas funções que chamei de $ MAP e $ FILTER. Então, como eles são?
Como você pode ver, ambas as funções pegam o acumulador $ e o devolvem novamente. Existem duas diferenças nessas funções:
Observe que isso está longe de ser trivial; podemos usá-lo para tornar nossos algoritmos mais eficientes!
Muitas vezes, podemos ver código como esses dois exemplos:
Usar array_map e array_filter em vez de loops faz com que esses exemplos pareçam bastante agradáveis. No entanto, pode ser muito ineficiente se $ inputs for grande, pois a primeira chamada (mapa ou filtro) percorrerá $ inputs e criará uma matriz intermediária. Essa matriz intermediária é passada diretamente para a segunda chamada, que percorrerá a coisa toda novamente, e a matriz intermediária precisará ser coletada como lixo.
Podemos nos livrar dessa matriz intermediária explorando o fato de que array_map e array_filter são exemplos de array_reduce. Ao combiná-los, precisamos apenas percorrer $ inputs uma vez em cada exemplo:
NOTA: Minhas implementações de array_map e array_filter acima não se comportarão exatamente como as do PHP, pois meu array_map pode lidar apenas com uma matriz de cada vez e meu array_filter não usará "vazio" como sua função $ padrão. Além disso, nenhum dos dois preservará as chaves.
Não é difícil fazê-los se comportar como os do PHP, mas senti que essas complicações dificultariam a identificação da ideia principal.
fonte
A revisão a seguir procura delinear com mais clareza array_filer (), array_map () e array_walk () do PHP, todos originários da programação funcional:
array_filter () filtra os dados, produzindo como resultado uma nova matriz contendo apenas os itens desejados da matriz anterior, da seguinte maneira:
código ao vivo aqui
Todos os valores numéricos são filtrados de $ array, deixando $ filtrado apenas com tipos de frutas.
array_map () também cria uma nova matriz, mas, diferentemente de array_filter (), a matriz resultante contém todos os elementos da entrada $ filtrados, mas com valores alterados, devido à aplicação de um retorno de chamada para cada elemento, da seguinte maneira:
código ao vivo aqui
O código nesse caso aplica um retorno de chamada usando o strtoupper () interno, mas uma função definida pelo usuário também é outra opção viável. O retorno de chamada se aplica a todos os itens de $ filtrados e, assim, gera $ nu cujos elementos contêm valores em maiúsculas.
No próximo trecho, o array walk () percorre $ nu e faz alterações em cada elemento em relação ao operador de referência '&'. As alterações ocorrem sem criar uma matriz adicional. O valor de cada elemento é alterado para uma sequência mais informativa, especificando sua chave, categoria e valor.
Ver demonstração
Nota: a função de retorno de chamada em relação a array_walk () usa dois parâmetros que adquirem automaticamente o valor de um elemento e sua chave e nessa ordem, também quando são invocados por array_walk (). (Veja mais aqui ).
fonte
$lambda
e$callback
são apenas etaexpansões de funções existentes e, portanto, são completamente redundantes. Você pode obter o mesmo resultado passando (o nome da) a função subjacente:$filtered = array_filter($array, 'ctype_alpha');
e$nu = array_map('strtoupper', $filtered);