Array-Element nach Wert entfernen

166

Ich muss das Array-Element mit dem angegebenen Wert entfernen:

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

Könnte es kürzer (effizienter) gemacht werden?

Marek
quelle
1
Mögliches Duplikat des PHP-Arrays nach Wert löschen (nicht Schlüssel)
Ben

Antworten:

423

Dies kann mit einem einfachen Einzeiler erreicht werden.

Mit diesem Array:

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

Du kannst tun:

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

Und der Wert von $arrwird sein:

array('nice_item', 'another_liked_item')

Hoffe, es hilft, schönen Code zu schreiben.

Alejandro García Iglesias
quelle
2
Nein, es tut Arbeiten mit referenzierten Arrays, die array_diffFunktion ist zerstörungsfrei , es gibt ein neues Array.
Alejandro García Iglesias
2
@srcspider warum nicht? $referenced = array_diff($referenced, $items_to_remove);
Alejandro García Iglesias
1
$ referenziert zeigt jetzt auf ein neues Array. Das Array, das Sie ändern möchten, hat immer noch die alten Werte.
srcspider
2
@srcspider gut, Sie sagen mir, was hier dann los ist ... codepad.org/11ZhiFP0
Alejandro García Iglesias
1
mein Fehler; PHPs Variable Aliasing Gimmick
stolpert
37

Ich füge eine zweite Antwort hinzu. Ich habe ein schnelles Benchmarking-Skript geschrieben, um hier verschiedene Methoden auszuprobieren.

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

Die dritte Methode array_keys()mit dem angegebenen optionalen Suchparameter scheint bei weitem die beste Methode zu sein. Ausgabebeispiel:

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

Demnach wäre die Lösung, die ich dann verwenden würde:

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}
Zombat
quelle
Ich denke, array_search ist viel besser lesbarer Code als die Verwendung der array_diff-Methode. Upvote
Kendepelchin
@zombat Ich frage mich, ob die Bestellung etwas mit den Ergebnissen zu tun hat. Es ist möglich, dass durch Mischen der gesuchte Wert entweder näher an der Vorderseite oder am Ende platziert wird.
General Redneck
31

Wie wäre es mit:

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

oder für mehrere Werte:

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

Dies würde auch einen Schlüsselverlust verhindern, was ein Nebeneffekt von ist array_flip().

Zombat
quelle
1
funktioniert nicht, wenn $ id das erste Array-Element ist, besser so: if (($ key = array_search ($ id, $ items))! == false) unset ($ items [$ key]);
Marek
15

zu entfernen $rm_valvon$arr

unset($arr[array_search($rm_val, $arr)]);
Toma
quelle
8

Die leistungsstärkste Lösung wäre die Verwendung array_filter, mit der Sie Ihre eigene Filterfunktion definieren können.

Aber einige könnten sagen, dass es in Ihrer Situation ein bisschen übertrieben ist ...
Eine einfache foreachSchleife, um durch das Array zu gehen und das Element zu entfernen, das Sie nicht wollen, sollte ausreichen.

So etwas sollte in Ihrem Fall wahrscheinlich den Trick machen:

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;
    }
}
Pascal MARTIN
quelle
6

Versuchen Sie array_search ()

Savageman
quelle
3
Ich habe gerade die Dokumentation gelesen und es wird empfohlen, array_keys () zu verwenden, um alle einem Wert zugeordneten Schlüssel zu finden.
Savageman
@ Savageman - Einverstanden. Ich habe einen schnellen Benchmark durchgeführt und array_keys()scheint besser abzuschneiden als array_search()bei dieser Aufgabe.
Zombat
6

Ihre Lösungen funktionieren nur, wenn Ihr Array eindeutige Werte enthält

Sehen:

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

Ein besserer Weg wäre, mit array_search in einer Schleife, falls erforderlich, nicht gesetzt zu werden.

Dutow
quelle
Sie haben Recht, aber in diesem speziellen Fall bin ich mir ziemlich sicher, dass die Werte eindeutig sind :)
Marek
5

ohne Flip:

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}
erenon
quelle
5
function deleteValyeFromArray($array,$value)
{
   foreach($array as $key=>$val)
   {
      if($val == $value)
      {
         unset($array[$key]);
      }
   }
   return $array;
}
Suman Biswas
quelle
4

Sie können die Funktion array_splice für diese Operation verwenden. Ref: array_splice

array_splice($array, array_search(58, $array ), 1);
Tejas Soni
quelle