177

I need to remove array item with given value:

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

Could it be done in shorter (more efficient) way?

Marek
  • 2,681
  • 3
  • 22
  • 18

10 Answers10

435

It can be accomplished with a simple one-liner.

Having this array:

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

You can do:

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

And the value of $arr will be:

array('nice_item', 'another_liked_item')
Kavin-K
  • 1,948
  • 3
  • 17
  • 48
Alejandro García Iglesias
  • 16,222
  • 11
  • 51
  • 64
37

I am adding a second answer. I wrote a quick benchmarking script to try various methods here.

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

The third method, array_keys() with the optional search parameter specified, seems to be by far the best method. Output example:

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

Judging by this, the solution I would use then would be:

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}
zombat
  • 92,731
  • 24
  • 156
  • 164
  • I think array_search is much more readable code than using the array_diff method. Upvote – kendepelchin Jan 21 '13 at 16:28
  • @zombat I wonder if order has anything to do with the results. It is possible that shuffle put the value we are searching for either closer to the front or end. Other than that... +1 – General Redneck Jun 29 '16 at 17:57
34

How about:

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

or for multiple values:

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

This would prevent key loss as well, which is a side effect of array_flip().

zombat
  • 92,731
  • 24
  • 156
  • 164
  • 1
    won't work if $id is first array element, better this way: if ( ($key = array_search($id, $items)) !== false) unset($items[$key]); – Marek Dec 10 '09 at 19:50
17

to remove $rm_val from $arr

unset($arr[array_search($rm_val, $arr)]);
gturri
  • 13,807
  • 9
  • 40
  • 57
Toma
  • 171
  • 1
  • 2
8

The most powerful solution would be using array_filter, which allows you to define your own filtering function.

But some might say it's a bit overkill, in your situation...
A simple foreach loop to go trough the array and remove the item you don't want should be enough.

Something like this, in your case, should probably do the trick :

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
  • 395,085
  • 80
  • 655
  • 663
6

Try array_search()

Savageman
  • 9,257
  • 6
  • 40
  • 50
  • 3
    I just read the documentation, and it recommend to use array_keys() to find all the keys associated to a value. – Savageman Dec 10 '09 at 19:40
  • @Savageman - Agreed. I ran a quick benchmark and `array_keys()` seems to perform better than `array_search()` for this task. – zombat Dec 10 '09 at 20:06
6

Your solutions only work if you have unique values in your array

See:

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

A better way would be unset with array_search, in a loop if neccessary.

Dutow
  • 5,638
  • 1
  • 30
  • 40
5

w/o flip:

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}
erenon
  • 18,838
  • 2
  • 61
  • 93
5
function deleteValyeFromArray($array,$value)
{
   foreach($array as $key=>$val)
   {
      if($val == $value)
      {
         unset($array[$key]);
      }
   }
   return $array;
}
Suman Biswas
  • 853
  • 10
  • 19
4

You can use array_splice function for this operation Ref : array_splice

array_splice($array, array_search(58, $array ), 1);
Tejas Soni
  • 551
  • 3
  • 10