Suppression d'un élément de tableau par valeur


166

J'ai besoin de supprimer l'élément de tableau avec une valeur donnée:

if (in_array($id, $items)) {
    $items = array_flip($items);
    unset($items[ $id ]);
    $items = array_flip($items);
}

Cela pourrait-il être fait de manière plus courte (plus efficace)?


Réponses:


423

Cela peut être accompli avec une simple doublure.

Avoir ce tableau:

$arr = array('nice_item', 'remove_me', 'another_liked_item', 'remove_me_also');

Tu peux faire:

$arr = array_diff($arr, array('remove_me', 'remove_me_also'));

Et la valeur de $arrsera:

array('nice_item', 'another_liked_item')

J'espère que cela aidera à écrire un beau code.


2
Non, il ne fonctionne avec des tableaux référencés, la array_difffonction est non destructive, elle retourne un nouveau tableau.
Alejandro García Iglesias

2
@srcspider pourquoi pas? $referenced = array_diff($referenced, $items_to_remove);
Alejandro García Iglesias

1
$ referenced pointe maintenant vers un nouveau tableau, le tableau que vous vouliez changer a toujours les anciennes valeurs.
srcspider

2
@srcspider eh bien, dites-moi ce qui se passe ici alors ... codepad.org/11ZhiFP0
Alejandro García Iglesias

1
ma faute; Le gimmick d'aliasing variable de php me fait toujours
trébucher

37

J'ajoute une deuxième réponse. J'ai écrit un script d'analyse comparative rapide pour essayer différentes méthodes ici.

$arr = array(0 => 123456);
for($i = 1; $i < 500000; $i++) {
    $arr[$i] = rand(0,PHP_INT_MAX);
}

shuffle($arr);
$arr2 = $arr;
$arr3 = $arr;

/** 
 * Method 1 - array_search()
 */
$start = microtime(true);
while(($key = array_search(123456,$arr)) !== false) {
    unset($arr[$key]);
}
echo count($arr). ' left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 2 - basic loop
 */
$start = microtime(true);
foreach($arr2 as $k => $v) {
    if ($v == 123456) {
        unset($arr2[$k]);
    }
}
echo count($arr2). 'left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 3 - array_keys() with search parameter
 */
$start = microtime(true);
$keys = array_keys($arr3,123456);
foreach($keys as $k) {
    unset($arr3[$k]);
}
echo count($arr3). 'left, in '.(microtime(true) - $start).' seconds<BR>';

La troisième méthode, array_keys()avec le paramètre de recherche facultatif spécifié, semble être de loin la meilleure méthode. Exemple de sortie:

499999 left, in 0.090957164764404 seconds
499999left, in 0.43156313896179 seconds
499999left, in 0.028877019882202 seconds

À en juger par cela, la solution que j'utiliserais alors serait:

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}

Je pense que array_search est un code beaucoup plus lisible que d'utiliser la méthode array_diff. Upvote
kendepelchin

@zombat Je me demande si l'ordre a quelque chose à voir avec les résultats. Il est possible que la lecture aléatoire place la valeur recherchée plus près du front ou de la fin. Autre que ça ... +1
General Redneck

31

Que diriez-vous:

if (($key = array_search($id, $items)) !== false) unset($items[$key]);

ou pour plusieurs valeurs:

while(($key = array_search($id, $items)) !== false) {
    unset($items[$key]);
}

Cela éviterait également la perte de clés, ce qui est un effet secondaire de array_flip().


1
ne fonctionnera pas si $ id est le premier élément du tableau, mieux de cette façon: if (($ key = array_search ($ id, $ items))! == false) unset ($ items [$ key]);
Marek

15

supprimer $rm_valde$arr

unset($arr[array_search($rm_val, $arr)]);

8

La solution la plus puissante serait d'utiliser array_filter, qui vous permet de définir votre propre fonction de filtrage.

Mais certains pourraient dire que c'est un peu exagéré, dans votre situation ...
Une simple foreachboucle pour parcourir le tableau et supprimer l'élément que vous ne voulez pas devrait suffire.

Quelque chose comme ça, dans votre cas, devrait probablement faire l'affaire:

foreach ($items as $key => $value) {
    if ($value == $id) {
        unset($items[$key]);
        // If you know you only have one line to remove, you can decomment the next line, to stop looping
        //break;
    }
}

6

Essayez array_search ()


3
Je viens de lire la documentation, et il est recommandé d'utiliser array_keys () pour trouver toutes les clés associées à une valeur.
Savageman

@Savageman - D'accord. J'ai effectué un test rapide et array_keys()semble mieux performer que array_search()pour cette tâche.
zombat

6

Vos solutions ne fonctionnent que si vous avez des valeurs uniques dans votre tableau

Voir:

<?php
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
?>

Un meilleur moyen serait de ne pas être défini avec array_search , dans une boucle si nécessaire.


vous avez raison, mais dans ce cas particulier, je suis presque sûr que les valeurs sont uniques :)
Marek

5

sans flip:

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}

5
function deleteValyeFromArray($array,$value)
{
   foreach($array as $key=>$val)
   {
      if($val == $value)
      {
         unset($array[$key]);
      }
   }
   return $array;
}

4

Vous pouvez utiliser la fonction array_splice pour cette opération Ref: array_splice

array_splice($array, array_search(58, $array ), 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.