Après array_filter (), comment puis-je réinitialiser les clés pour aller dans l'ordre numérique à partir de 0


108

Je viens d'utiliser array_filter pour supprimer les entrées qui n'avaient que la valeur '' d'un tableau, et maintenant je veux y appliquer certaines transformations en fonction de l'espace réservé à partir de 0, mais malheureusement, il conserve toujours l'index d'origine. J'ai cherché pendant un moment et je n'ai rien vu, peut-être que j'ai juste raté l'évidence, mais ma question est ...

Comment puis-je facilement réinitialiser les index du tableau pour commencer à 0 et aller dans l'ordre dans le nouveau tableau, plutôt que de lui faire conserver les anciens index?



Sauf si vous êtes absolument certain de ne pas avoir de valeurs vides / zéro-ish / falsey dans votre tableau, je dois vous exhorter à ne pas utiliser array_filter()- vous pouvez en purger plus que vous ne le souhaitez. Voici quelques explications avec une démo: stackoverflow.com/a/43657056/2943403
mickmackusa

Réponses:



37

Si vous utilisez le filtre Array, procédez comme suit

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

3
Oh le temps que j'ai perdu à essayer de comprendre pourquoi le résultat de json_encode d'un tableau est différent de celui de json_encode d'un tableau array_filtered ... merci BEAUCOUP ...
Jerther

13

Je m'inquiète du nombre de programmeurs qui ont innocemment copié / collé la array_values(array_filter())méthode dans leurs codes - je me demande combien de programmeurs ont involontairement rencontré des problèmes à cause de la cupidité de array_filter. Ou pire, combien de personnes n'ont jamais découvert que la fonction purge trop de valeurs du tableau ...

Je présenterai une meilleure alternative pour le processus en deux parties consistant à retirer des NULLéléments d'un tableau et à réindexer les clés.

Cependant, tout d'abord, il est extrêmement important que je souligne la nature gourmande array_filter()et comment cela peut silencieusement monkeywrench votre projet. Voici un tableau avec des valeurs mixtes qui exposeront le problème:

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

Les valeurs nulles seront supprimées indépendamment des majuscules / minuscules.

Mais regardez ce qui reste dans le tableau lorsque nous utilisons array_values ​​() & array_filter () :

array_values(array_filter($array));

Tableau de sortie ($ array):

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

Maintenant, regardez ce que vous obtenez avec ma méthode qui utilise array_walk () & is_null () pour générer un nouveau tableau filtré:

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

Cela peut être écrit sur plusieurs lignes pour une lecture / explication plus facile:

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

Tableau de sortie ($ filter):

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

Avec ma méthode, vous obtenez vos clés réindexées, toutes les valeurs non nulles et aucune des valeurs nulles. Un monocouche propre, portable et fiable pour tous vos besoins en matière de filtrage nul des baies. Voici une démonstration .



De même, si vous souhaitez supprimer des éléments vides, faux et nuls (en conservant les zéros), ces quatre méthodes fonctionneront:

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

Production:

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

Enfin, pour quiconque préfère la syntaxe des constructions de langage, vous pouvez également simplement pousser les valeurs de qualification dans un nouveau tableau pour émettre de nouveaux index.

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

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

var_export($result);

2
Les choses ne se comporteront-elles pas exactement comme prévu si vous écrivez array_values(array_filter($arr, function($el) {return $el !== '';}))? Cela semble être la manière naturelle de faire ce que le PO demande.
Casey

1
Oui. Mon point est que les développeurs devraient éviter l'envie d'utiliser le comportement par défaut de, à array_filter()moins que leur connaissance intime des données ne permette un filtrage gourmand sans effets secondaires. (Une autre mise en garde: empty()se comporte de la même manière et inclut également un tableau vide dans sa gourmandise.)
mickmackusa

2
Cette réponse répond à une question complètement différente, sans rapport avec l'original en aucune manière, forme ou forme.
AnrDaemon

1
array_filter()se comporte exactement comme vous vous y attendez en fonction de ce qui est dit dans le manuel: php.net/manual/en/function.array-filter.php "Si aucun rappel n'est fourni, toutes les entrées du tableau sont égales à FALSE (voir conversion en booléen ) sera supprimé. " Et il devrait être de notoriété publique parmi les programmeurs PHP que 0, null, false, «» et «0» évaluent tous à faux lorsqu'ils sont forcés à booléen.
madsen

1
Le fait est que la plupart des gens ne savent pas à quoi s'attendre. Vous faites, je le fais, mais beaucoup ne le font pas. J'ai posté cette réponse pour aider les gens qui ne savent pas.
mickmackusa

12

Utilisez 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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.