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.