Después de array_filter (), ¿cómo puedo restablecer las teclas para que vayan en orden numérico a partir de 0?


108

Acabo de usar array_filter para eliminar las entradas que solo tenían el valor '' de una matriz, y ahora quiero aplicar ciertas transformaciones en función del marcador de posición a partir de 0, pero desafortunadamente aún conserva el índice original. Busqué por un tiempo y no pude ver nada, tal vez simplemente me perdí lo obvio, pero mi pregunta es ...

¿Cómo puedo restablecer fácilmente los índices de la matriz para que comiencen en 0 y vayan en orden en la NUEVA matriz, en lugar de que conserve los índices antiguos?



A menos que esté absolutamente seguro de que no tiene ningún valor vacío / cero-ish / falsey en su matriz, debo instarle a que no lo use array_filter(); puede purgar más de lo que pretende. Aquí hay una explicación con una demostración: stackoverflow.com/a/43657056/2943403
mickmackusa

Respuestas:



37

Si está utilizando un filtro de matriz, hágalo de la siguiente manera

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

3
Oh, el tiempo que he perdido tratando de averiguar por qué el resultado de json_encode una matriz es diferente al de json_encode una matriz array_filtered ... MUCHAS gracias ...
Jerther

13

Me preocupa cuántos programadores han copiado / pegado inocentemente el array_values(array_filter())método en sus códigos ; me pregunto cuántos programadores sin saberlo se encontraron con problemas debido a la codicia de array_filter. O peor aún, cuántas personas nunca descubrieron que la función elimina demasiados valores de la matriz ...

Presentaré una mejor alternativa para el proceso de dos partes de quitar NULLelementos de una matriz y volver a indexar las claves.

Sin embargo, primero, es extremadamente importante que array_filter()haga hincapié en la naturaleza codiciosa y cómo esto puede destrozar silenciosamente su proyecto. Aquí hay una matriz con valores mixtos que expondrá el problema:

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

Los valores nulos se eliminarán independientemente de mayúsculas / minúsculas.

Pero mire lo que queda en la matriz cuando usamos array_values ​​() & array_filter () :

array_values(array_filter($array));

Matriz de salida ($ matriz):

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

Ahora mire lo que obtiene con mi método que usa array_walk () & is_null () para generar una nueva matriz filtrada:

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

Esto se puede escribir en varias líneas para facilitar la lectura / explicación:

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 salida ($ filtro):

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

Con mi método, obtiene sus claves reindexadas, todos los valores no nulos y ninguno de los valores nulos. Una sola línea limpia, portátil y confiable para todas sus necesidades de filtrado nulo de arreglos. He aquí una demostración .



De manera similar, si desea eliminar elementos vacíos, falsos y nulos (conservando ceros), estos cuatro métodos funcionarán:

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

Salida:

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

Finalmente, para cualquiera que prefiera la sintaxis de construcciones de lenguaje, también puede simplemente insertar valores de calificación en una nueva matriz para emitir nuevos índices.

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

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

var_export($result);

2
¿No se comportarán las cosas exactamente de la manera esperada si escribe array_values(array_filter($arr, function($el) {return $el !== '';}))? Esa parece la forma natural de hacer lo que pide el OP.
Casey

1
Si. Mi punto es que los desarrolladores deben evitar la tentación de utilizar el comportamiento predeterminado de a array_filter()menos que su conocimiento íntimo de los datos permita un filtrado codicioso sin efectos secundarios. (Una advertencia adicional: se empty()comporta de la misma manera y también incluye una matriz vacía en su codicia.)
mickmackusa

2
Esta respuesta responde a una pregunta completamente diferente, no relacionada con la original de ninguna manera, forma o forma.
AnrDaemon

1
array_filter()se comporta exactamente como cabría esperar en función de lo que dice en el manual: php.net/manual/en/function.array-filter.php "Si no se proporciona ninguna devolución de llamada, todas las entradas de la matriz son iguales a FALSE (consulte conversión a boolean ) será eliminado ". Y debería ser de conocimiento común entre los programadores de PHP que 0, nulo, falso, '' y '0' se evalúan como falso cuando se coaccionan a booleano.
madsen

1
La cosa es que la mayoría de la gente no sabe qué esperar. Tú lo haces, yo lo hago, pero muchos no lo hacen. Publiqué esta respuesta para ayudar a las personas que no saben.
mickmackusa

12

Utilizar 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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.