Rebase des clés de tableau après avoir désactivé des éléments [dupliquer]

185

J'ai un tableau:

$array = array(1,2,3,4,5);

Si je devais vider le contenu du tableau, ils ressembleraient à ceci:

array(5) {
  [0] => int(1)
  [1] => int(2)
  [2] => int(3)
  [3] => int(4)
  [4] => int(5)
}

Quand je passe en boucle et désactive certaines touches, l'index est tout relevé.

foreach($array as $i => $info)
{
  if($info == 1 || $info == 2)
  {
    unset($array[$i]);
  }
}

Par la suite, si je faisais un autre vidage maintenant, cela ressemblerait à:

array(3) {
  [2] => int(3)
  [3] => int(4)
  [4] => int(5)
}

Existe-t-il un moyen approprié de réinitialiser le tableau pour que ses éléments soient à nouveau basés sur zéro?

array(3) {
  [0] => int(3)
  [1] => int(4)
  [2] => int(5)
}
TuK
la source

Réponses:

423

Essaye ça:

$array = array_values($array);

Utilisation de array_values ​​()

Naftali alias Neal
la source
6
+1. Je note que le manuel n'indique pas explicitement que la commande sera maintenue, mais je ne vois pas pourquoi ce ne serait pas le cas.
Courses de légèreté en orbite
17
Oui, la commande est définitivement maintenue. Ce serait une fonction hideuse s'il le réorganisait! :)
webbiedave
1
@webbiedave désolé, mais ce n'est pas vrai. Il réorganise en fait mon tableau. Très très étrange.
FooBar
4
optez toujours pour les solutions simples et concises :)
Bruce Lim
1
Bien que ce soit une solution simple lorsque le tableau est déjà numéroté, cela ne fonctionne pas lorsque la clé est définie en tant que texte, comme elle le ferait dans le cadre d'un formulaire HTML. Si vous comptez sur des valeurs de clé uniques pour identifier la sortie d'un formulaire, l'une des méthodes ci-dessous fonctionne mieux.
17

Vous avez une autre méthode intéressante:

$array = array('a', 'b', 'c', 'd'); 
unset($array[2]); 

$array = array_merge($array); 

Maintenant, les clés $ array sont réinitialisées.

Développeur web
la source
13

Utilisez array_spliceplutôt que unset:

$array = array(1,2,3,4,5);
foreach($array as $i => $info)
{
  if($info == 1 || $info == 2)
  {
    array_splice($array, $i, 1);
  }
}

print_r($array);

Exemple de travail ici .

Demian Brecht
la source
8
Cela ne fonctionne pas. splice serait génial mais vous ne pouvez pas l'utiliser dans une boucle for / foreach car il réorganise l'index à chaque fois que vous l'appelez, donc l'index de la boucle foreach ne pointe pas vers l'élément suivant mais vers l'élément avec cette position sur la matrice réorganisée. Vous pouvez voir dans votre exemple que vous supprimez la valeur «3» et que vous laissez la valeur «2» alors que vous ne devriez supprimer que les valeurs «1» et «2»
NotGaeL
1
@elcodedocle Alors n'utilisez pas de foreachboucle. Utilisez la norme i Loopet réinitialisez simplement i après une épissure. En outre, Working sample here.ne fonctionne pas.
SpYk3HH
Lien brisé, pourriez-vous le réparer?
Michel Ayres
6

Juste un additif.

Je sais que c'est vieux , mais je voulais ajouter une solution que je ne vois pas que j'ai trouvée moi-même. J'ai trouvé cette question alors que je cherchais une solution différente et je me suis simplement dit: "Eh bien, pendant que je suis ici."

Tout d'abord, la réponse de Neal est bonne et géniale à utiliser après avoir exécuté votre boucle, cependant, je préférerais faire tout le travail en même temps. Bien sûr, dans mon cas particulier, j'ai dû faire plus de travail que cet exemple simple ici, mais la méthode s'applique toujours. J'ai vu où quelques autres ont suggéré des foreachboucles, cependant, cela vous laisse toujours après le travail en raison de la nature de la bête. Normalement, je suggère des choses plus simples comme foreach, cependant, dans ce cas, il est préférable de se souvenir de la bonne for looplogique à l' ancienne . Utilisez simplement i! Pour conserver un index approprié, il suffit de soustraire iaprès chaque suppression d'un élément de tableau.

Voici mon exemple simple et fonctionnel :

$array = array(1,2,3,4,5);

for ($i = 0; $i < count($array); $i++) {
    if($array[$i] == 1 || $array[$i] == 2) {
        array_splice($array, $i, 1);
        $i--;
    }
}

Sortira:

array(3) {
    [0]=> int(3)
    [1]=> int(4)
    [2]=> int(5)
}

Cela peut avoir de nombreuses implémentations simples. Par exemple, mon cas exact nécessitait la tenue du dernier élément du tableau en fonction de valeurs multidimensionnelles. Je vais vous montrer ce que je veux dire:

$files = array(
    array(
        'name' => 'example.zip',
        'size' => '100000000',
        'type' => 'application/x-zip-compressed',
        'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
        'deleteUrl' => 'server/php/?file=example.zip',
        'deleteType' => 'DELETE'
    ),
    array(
        'name' => 'example.zip',
        'size' => '10726556',
        'type' => 'application/x-zip-compressed',
        'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
        'deleteUrl' => 'server/php/?file=example.zip',
        'deleteType' => 'DELETE'
    ),
    array(
        'name' => 'example.zip',
        'size' => '110726556',
        'type' => 'application/x-zip-compressed',
        'deleteUrl' => 'server/php/?file=example.zip',
        'deleteType' => 'DELETE'
    ),
    array(
        'name' => 'example2.zip',
        'size' => '12356556',
        'type' => 'application/x-zip-compressed',
        'url' => '28188b90db990f5c5f75eb960a643b96/example2.zip',
        'deleteUrl' => 'server/php/?file=example2.zip',
        'deleteType' => 'DELETE'
    )
);

for ($i = 0; $i < count($files); $i++) {
    if ($i > 0) {
        if (is_array($files[$i-1])) {
            if (!key_exists('name', array_diff($files[$i], $files[$i-1]))) {
                if (!key_exists('url', $files[$i]) && key_exists('url', $files[$i-1])) $files[$i]['url'] = $files[$i-1]['url'];
                $i--;
                array_splice($files, $i, 1);
            }
        }
    }
}

Sortira:

array(1) {
    [0]=> array(6) {
            ["name"]=> string(11) "example.zip"
            ["size"]=> string(9) "110726556"
            ["type"]=> string(28) "application/x-zip-compressed"
            ["deleteUrl"]=> string(28) "server/php/?file=example.zip"
            ["deleteType"]=> string(6) "DELETE"
            ["url"]=> string(44) "28188b90db990f5c5f75eb960a643b96/example.zip"
        }
    [1]=> array(6) {
            ["name"]=> string(11) "example2.zip"
            ["size"]=> string(9) "12356556"
            ["type"]=> string(28) "application/x-zip-compressed"
            ["deleteUrl"]=> string(28) "server/php/?file=example2.zip"
            ["deleteType"]=> string(6) "DELETE"
            ["url"]=> string(45) "28188b90db990f5c5f75eb960a643b96/example2.zip"
        }
}

Comme vous le voyez, je manipule $ i avant l'épissure car je cherche à supprimer l'élément précédent plutôt que le présent.

SpYk3HH
la source
Solution parfaite splicepour les très gros tableaux, car aucune copie n'est nécessaire. Donc je n'ai pas de problèmes de mémoire.
Sascha le
1

Réponse tardive mais, après PHP 5.3, cela pourrait être le cas;

$array = array(1, 2, 3, 4, 5);
$array = array_values(array_filter($array, function($v) {
    return !($v == 1 || $v == 2);
}));
print_r($array);
K-Gun
la source
1

Ou vous pouvez créer votre propre fonction qui transmet le tableau par référence.

function array_unset($unsets, &$array) {
  foreach ($array as $key => $value) {
    foreach ($unsets as $unset) {
      if ($value == $unset) {
        unset($array[$key]);
        break;
      }
    }
  }
  $array = array_values($array);
}

Alors tout ce que vous avez à faire est ...

$unsets = array(1,2);
array_unset($unsets, $array);

... et maintenant vous n'avez plus $arrayles valeurs que vous avez placées $unsetset les clés sont réinitialisées

bouleversé
la source
1

100% travaille pour moi! Après avoir annulé les éléments du tableau, vous pouvez l'utiliser pour réindexer le tableau

$result=array_combine(range(1, count($your_array)), array_values($your_array));
Atta Ur Rehman
la source
0

J'utilise $arr = array_merge($arr); pour rebaser un tableau. Simple et direct.

Rockin4Life33
la source
-2

Dans ma situation, je devais conserver des clés uniques avec les valeurs du tableau, alors j'ai juste utilisé un deuxième tableau:

$arr1 = array("alpha"=>"bravo","charlie"=>"delta","echo"=>"foxtrot");
unset($arr1);

$arr2 = array();
foreach($arr1 as $key=>$value) $arr2[$key] = $value;
$arr1 = $arr2
unset($arr2);
John K
la source
1) Vous unset($arr1)qui ne le rendrez PAS disponible pour itérer dans votre boucle. 2) Il vous manque le point-virgule sur l'avant-dernière ligne. Cet extrait de code ne s'exécutera pas.
Rockin4Life33