Depois de array_filter (), como posso redefinir as chaves para ir em ordem numérica começando em 0

108

Acabei de usar array_filter para remover entradas que tinham apenas o valor '' de uma matriz e agora quero aplicar certas transformações dependendo do marcador começando em 0, mas infelizmente ainda mantém o índice original. Eu olhei por um tempo e não consegui ver nada, talvez eu só tenha perdido o óbvio, mas minha pergunta é ...

Como posso redefinir facilmente os índices da matriz para começar em 0 e ir em ordem na nova matriz, em vez de manter os índices antigos?

jel402
fonte
Possível duplicata de php array_filter sem preservação de chave
Yep_It's_Me
A menos que você esteja absolutamente certo de que não possui nenhum valor vazio / zero-ish / falsey em seu array, recomendo que você não use array_filter()- você pode purgar mais do que pretende. Aqui está uma explicação com uma demonstração: stackoverflow.com/a/43657056/2943403
mickmackusa

Respostas:

37

Se você estiver usando o filtro Array, faça o seguinte

$NewArray = array_values(array_filter($OldArray));
user2182143
fonte
3
Ah, que tempo perdi tentando descobrir por que o resultado de json_encode an array é diferente do resultado de json_encode an array_filtered array ... MUITO obrigado ...
Jerther
13

Eu me preocupo com quantos programadores inocentemente copiaram / colaram o array_values(array_filter())método em seus códigos - eu me pergunto quantos programadores inconscientemente tiveram problemas por causa da ganância de array_filter. Ou pior, quantas pessoas nunca descobriram que a função elimina muitos valores da matriz ...

Apresentarei uma alternativa melhor para o processo de duas partes de remoção de NULLelementos de uma matriz e reindexação das chaves.

No entanto, em primeiro lugar, é extremamente importante enfatizar a natureza gananciosa array_filter()e como isso pode perturbar silenciosamente seu projeto. Aqui está uma matriz com valores mistos que irá expor o problema:

$array=['foo',NULL,'bar',0,false,null,'0',''];

Os valores nulos serão removidos independentemente de maiúsculas / minúsculas.

Mas veja o que permanece na matriz quando usamos array_values ​​() & array_filter () :

array_values(array_filter($array));

Matriz de saída ($ array):

array (
  0 => 'foo',
  1 => 'bar'
)
// All empty, zero-ish, falsey values were removed too!!!

Agora veja o que você obtém com meu método que usa array_walk () & is_null () para gerar uma nova matriz filtrada:

array_walk($array,function($v)use(&$filtered){if(!is_null($v)){$filtered[]=$v;}});

Isso pode ser escrito em várias linhas para facilitar a leitura / explicação:

array_walk(                      // iterate each element of an input array
    $array,                      // this is the input array
    function($v)use(&$filtered){ // $v is each value, $filter (output) is declared/modifiable
        if(!is_null($v)){        // this literally checks for null values
            $filtered[]=$v;      // value is pushed into output with new indexes
        }
    }
);

Matriz de saída ($ filter):

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => false,
  4 => '0',
  5 => '',
)

Com meu método, você obtém suas chaves reindexadas, todos os valores não nulos e nenhum dos valores nulos. Um liner limpo, portátil e confiável para todas as suas necessidades de filtragem de nulos de array. Aqui está uma demonstração .



Da mesma forma, se você deseja remover elementos vazios, falsos e nulos (retendo zeros), estes quatro métodos funcionarão:

var_export(array_values(array_diff($array,[''])));

ou

var_export(array_values(array_diff($array,[null])));

ou

var_export(array_values(array_diff($array,[false])));

ou

var_export(array_values(array_filter($array,'strlen')));

Resultado:

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => '0',
)

Finalmente, para quem prefere a sintaxe de construções de linguagem, você também pode simplesmente inserir valores de qualificação em uma nova matriz para emitir novos índices.

$array=['foo', NULL, 'bar', 0, false, null, '0', ''];

$result = [];
foreach ($array as $value) {
    if (strlen($value)) {
        $result[] = $value;
    }
}

var_export($result);
Mickmackusa
fonte
2
As coisas não se comportarão exatamente da maneira esperada se você escrever array_values(array_filter($arr, function($el) {return $el !== '';}))? Essa parece ser a maneira natural de fazer o que o OP está pedindo.
Casey
1
Sim. Meu ponto é que os desenvolvedores devem evitar o impulso de usar o comportamento padrão de, a array_filter()menos que seu conhecimento íntimo dos dados permita uma filtragem gananciosa sem efeitos colaterais. (Um outro aviso: empty()se comporta da mesma maneira e também inclui uma matriz vazia em sua ganância.)
mickmackusa,
2
Esta resposta responde a uma pergunta completamente diferente, não relacionada à original de qualquer forma, forma ou forma.
AnrDaemon
1
array_filter()se comporta exatamente como você espera com base no que diz no manual: php.net/manual/en/function.array-filter.php "Se nenhum retorno de chamada for fornecido, todas as entradas do array são iguais a FALSE (consulte convertendo para booleano ) será removido." E deve ser do conhecimento comum entre os programadores de PHP que 0, null, false, '' e '0' são avaliados como falsos quando coagidos para booleanos.
madsen
1
O fato é que a maioria das pessoas não sabe o que esperar. Você quer, eu sim, mas muitos não. Postei esta resposta para ajudar pessoas que não sabem.
mickmackusa
12

Use array_values():

<?php

$array = array('foo', 'bar', 'baz');
$array = array_filter($array, function ($var) {
    return $var !== 'bar';
});

print_r($array); // indexes 0 and 2
print_r(array_values($array)); // indexes 0 and 1
Ed Mazur
fonte