2009-12-10 6 views
143

Je dois enlever élément du tableau de valeur donnée:Suppression de l'élément de tableau par valeur

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

Pourrait-il être effectué de manière plus court (plus efficace)?

+1

double possible de [tableau PHP supprimer par valeur (non clé)] (http://stackoverflow.com/questions/7225070/php-array-delete-by-value-not-key) – Ben

Répondre

384

Il peut être accompli avec un simple-liner.

Ayant ce tableau:

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

Vous pouvez faire:

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

Et la valeur de $arr sera:

array('nice_item', 'another_liked_item') 

Hope it helps écrire beau code.

+0

Seulement si vous avez le contrôle de la variable. Si vous l'avez reçu comme référence, cette méthode est inutilisable. – srcspider

+1

Non, ça * fonctionne * avec les tableaux référencés, la fonction 'array_diff' est non destructive, elle retourne un nouveau tableau. –

+0

Vous manquez mon point, si vous avez un tableau par référence et que vous voulez supprimer un élément, vous ne pouvez pas avec cette méthode. – srcspider

4

Essayez array_search()

+3

Je viens de lire la documentation, et il recommande d'utiliser un rray_keys() pour trouver toutes les clés associées à une valeur. – Savageman

+0

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

5

w/o FLIP:

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

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 qu'il est un peu exagéré, dans votre situation ...
Une boucle foreach simple à faire une dépression du tableau et supprimer l'élément que vous ne voulez pas devrait être suffisant.

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

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 empêcherait perte de clé ainsi, 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

+0

Bonne prise, je vais régler ça. – zombat

+0

Merci @zombat, ça a marché pour moi. – Pupil

5

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

Une meilleure façon serait unset avec array_search, dans une boucle si nécessaire.

+0

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

33

J'ajoute une deuxième réponse. J'ai écrit un script d'analyse 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 en option spécifiée, 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 

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

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

impressionnant - merci :) – Marek

+0

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

+0

@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 que nous recherchons plus près de l'avant ou de la fin. Autre que cela ... +1 –

14

pour enlever $rm_val de $arr

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

Vous pouvez utiliser array_splice fonction pour cette opération Réf: array_splice

array_splice($array, array_search(58, $array), 1); 
Questions connexes