tags:

views:

118

answers:

6

Hi

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?

+3  A: 

Try array_search()

Savageman
I just read the documentation, and it recommend to use array_keys() to find all the keys associated to a value.
Savageman
@Savageman - Agreed. I ran a quick benchmark and `array_keys()` seems to perform better than `array_search()` for this task.
zombat
+2  A: 

w/o flip:

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

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
+4  A: 

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
won't work if $id is first array element, better this way:if ( ($key = array_search($id, $items)) !== false) unset($items[$key]);
Marek
Good catch, I'll fix that.
zombat
+1  A: 

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
you are right, but in this particular case I'm pretty sure that values are unique :)
Marek
+2  A: 

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
impressive - thanks :)
Marek