Dopo array_filter (), come posso reimpostare i tasti per andare in ordine numerico a partire da 0


108

Ho appena usato array_filter per rimuovere le voci che avevano solo il valore '' da un array, e ora voglio applicare alcune trasformazioni su di esso a seconda del segnaposto a partire da 0, ma sfortunatamente mantiene ancora l'indice originale. Ho cercato per un po 'e non ho visto nulla, forse mi sono perso solo l'ovvio, ma la mia domanda è ...

Come posso reimpostare facilmente gli indici dell'array in modo che inizino da 0 e vadano in ordine nel NUOVO array, piuttosto che mantenere i vecchi indici?



A meno che tu non sia assolutamente certo di non avere alcun valore vuoto / zero / falso nel tuo array, devo esortarti a non usarlo array_filter(): potresti eliminare più di quanto intendi. Ecco qualche spiegazione con una demo: stackoverflow.com/a/43657056/2943403
mickmackusa

Risposte:



37

Se stai usando il filtro Array, fallo come segue

$NewArray = array_values(array_filter($OldArray));

3
Oh, il tempo che ho perso cercando di capire perché il risultato di json_encode un array è diverso da quello di json_encode un array_filtered array ... grazie MOLTO ...
Jerther

13

Mi preoccupo di quanti programmatori abbiano innocentemente copiato / incollato il array_values(array_filter())metodo nei loro codici - mi chiedo quanti programmatori abbiano inconsapevolmente incontrato problemi a causa dell'avidità di array_filter. O peggio, quante persone non hanno mai scoperto che la funzione elimina troppi valori dall'array ...

Presenterò un'alternativa migliore per il processo in due parti di rimozione di NULLelementi da un array e reindicizzazione delle chiavi.

Tuttavia, in primo luogo, è estremamente importante sottolineare la natura avida array_filter()e il modo in cui questo può silenziosamente stravolgere il tuo progetto. Ecco un array con valori misti al suo interno che esporrà il problema:

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

I valori nulli verranno rimossi indipendentemente da maiuscolo / minuscolo.

Ma guarda cosa rimane nell'array quando usiamo array_values ​​() e array_filter () :

array_values(array_filter($array));

Array di output ($ array):

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

Ora guarda cosa ottieni con il mio metodo che utilizza array_walk () e is_null () per generare un nuovo array filtrato:

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

Questo può essere scritto su più righe per facilitare la lettura / spiegazione:

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
        }
    }
);

Matrice di output ($ filtro):

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

Con il mio metodo ottieni le tue chiavi reindicizzate, tutti i valori non nulli e nessuno dei valori nulli. Un one-liner pulito, portatile e affidabile per tutte le esigenze di filtraggio null di array. Ecco una dimostrazione .



Allo stesso modo, se vuoi rimuovere elementi vuoti, falsi e nulli (mantenendo gli zeri), questi quattro metodi funzioneranno:

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

o

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

o

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

o

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

Produzione:

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

Infine, per chiunque preferisca la sintassi dei costrutti del linguaggio, è anche possibile inserire valori qualificanti in un nuovo array per emettere nuovi indici.

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

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

var_export($result);

2
Le cose non si comportano esattamente nel modo previsto se scrivi array_values(array_filter($arr, function($el) {return $el !== '';}))? Questo sembra il modo naturale per fare quello che chiede l'OP.
Casey

1
Sì. Il punto è che gli sviluppatori dovrebbero evitare l'impulso di utilizzare il comportamento predefinito di a array_filter()meno che la loro profonda conoscenza dei dati non consenta un filtraggio avido senza effetti collaterali. (Un'ulteriore avvertenza: empty()si comporta in questo stesso modo e include anche una matrice vuota nella sua avidità.)
mickmackusa

2
Questa risposta risponde a una domanda completamente diversa, non correlata a quella originale in alcun modo, forma o forma.
AnrDaemon

1
array_filter()si comporta esattamente come ti aspetteresti in base a ciò che dice nel manuale: php.net/manual/en/function.array-filter.php "Se non viene fornito alcun callback, tutte le voci di array sono uguali a FALSE (vedi conversione in booleano ) sarà rimosso." E dovrebbe essere una conoscenza comune tra i programmatori PHP che 0, null, false, "" e "0" restituiscono false se costrette a booleano.
madsen

1
Il fatto è che la maggior parte delle persone non sa cosa aspettarsi. Tu sì, ma molti no. Ho pubblicato questa risposta per aiutare le persone che non lo sanno.
mickmackusa

12

Usa 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.