155

I want to loop through an array with foreach to check if a value exists. If the value does exist, I want to delete the element which contains it.

I have the following code:

foreach($display_related_tags as $tag_name) {
    if($tag_name == $found_tag['name']) {
        // Delete element
    }
}

I don't know how to delete the element once the value is found. How do I delete it?

I have to use foreach for this problem. There are probably alternatives to foreach, and you are welcome to share them.

Kevin
  • 53,822
  • 15
  • 101
  • 132
ajsie
  • 77,632
  • 106
  • 276
  • 381
  • This question is missing its [mcve]. It does not make a great canonical reference and answerers are afforded the freedom to stretch the interpretation of the input data to diversify recommended solutions -- not great for the researcher experience. – mickmackusa May 18 '22 at 01:46

6 Answers6

256

If you also get the key, you can delete that item like this:

foreach ($display_related_tags as $key => $tag_name) {
    if($tag_name == $found_tag['name']) {
        unset($display_related_tags[$key]);
    }
}
Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 5
    Some additional info about optimizing by using `$key => &$tag_name` http://stackoverflow.com/a/2008893/922522 – Justin Oct 01 '15 at 18:57
  • 5
    Note that indexed arrays with items unset may be represented as objects instead of arrays after a `json_encode()`. You can solve this with `$display_related_tags = array_values ($display_related_tags);` after the `foreach` loop. – Márton Tamás Aug 11 '16 at 13:19
  • 1
    Note that's the trick here is to add a value to the foreach loop ;-) – Mr Washington Aug 17 '16 at 11:32
  • 6
    Please see @Neils answer. You will encounter unexpected bugs, especially if you work with Array of stdClasses. Do you like unexpected behavior? Me not. – happy_marmoset Sep 14 '16 at 11:44
  • @happy_marmoset Neils answer is not helping. Snippet `$projects = array_filter($projects, function ($project) { return count($project->roles) > 0; });` it converts result into object. – Paritosh Oct 06 '16 at 18:27
  • **Important** If you are interested in keeping the array as ordered array, you need to call `display_related_tags = array_values(display_related_tags);` after it. – guyaloni Jun 04 '20 at 11:49
48

A better solution is to use the array_filter function:

$display_related_tags =
    array_filter($display_related_tags, function($e) use($found_tag){
        return $e != $found_tag['name'];
    });

As the php documentation reads:

As foreach relies on the internal array pointer in PHP 5, changing it within the loop may lead to unexpected behavior.

In PHP 7, foreach does not use the internal array pointer.

Community
  • 1
  • 1
Neils
  • 1,513
  • 1
  • 12
  • 7
  • Note that the 3rd parameter should be ARRAY_FILTER_USE_KEY in order to pass the key as $e here. – namezero Feb 05 '18 at 12:13
  • @namezero OK why does that matter here? – AbraCadaver Feb 18 '20 at 12:52
  • @AbraCadaver From the documentation (https://www.php.net/manual/en/function.array-filter.php): `ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value ARRAY_FILTER_USE_BOTH - pass both value and key as arguments to callback instead of the value` `Default is 0 which will pass value as the only argument to callback instead. ` That said, reading the answer again in this case of course it would not matter as you claim. – namezero Feb 23 '20 at 11:49
  • **Important** If you are interested in keeping the array as ordered array, you need to call `display_related_tags = array_values(display_related_tags);` after it. – guyaloni Jun 04 '20 at 11:50
  • 1
    So, can we now say that it is safe, in PHP 7, to directly unset the item from the array? It definitely seems much leaner than using the `array_filter`, at least from the coder's perspective (I'm not sure about the actual implementation in the background). – userfuser Jan 08 '21 at 12:47
12
foreach($display_related_tags as $key => $tag_name)
{
    if($tag_name == $found_tag['name'])
        unset($display_related_tags[$key];
}
Steve H
  • 946
  • 9
  • 22
6

Instead of doing foreach() loop on the array, it would be faster to use array_search() to find the proper key. On small arrays, I would go with foreach for better readibility, but for bigger arrays, or often executed code, this should be a bit more optimal:

$result=array_search($unwantedValue,$array,true);
if($result !== false) {
  unset($array[$result]);   
}

The strict comparsion operator !== is needed, because array_search() can return 0 as the index of the $unwantedValue.

Also, the above example will remove just the first value $unwantedValue, if the $unwantedValue can occur more then once in the $array, You should use array_keys(), to find all of them:

$result=array_keys($array,$unwantedValue,true)
foreach($result as $key) {
  unset($array[$key]);
}

Check http://php.net/manual/en/function.array-search.php for more information.

PiotrN
  • 310
  • 1
  • 3
0

if you have scenario in which you have to remove more then one values from the foreach array in this case you have to pass value by reference in for each: I try to explain this scenario:

foreach ($manSkuQty as $man_sku => &$man_qty) {

               foreach ($manufacturerSkus as $key1 => $val1) {

  // some processing here and unset first loops entries                     
 //  here dont include again for next iterations
                           if(some condition)
                            unset($manSkuQty[$key1]);

                        }
               }
}

in second loop you want to unset first loops entries dont come again in the iteration for performance purpose or else then unset from memory as well because in memory they present and will come in iterations.

Hassan Ali Shahzad
  • 2,439
  • 29
  • 32
0

There are already answers which are giving light on how to unset. Rather than repeating code in all your classes make function like below and use it in code whenever required. In business logic, sometimes you don't want to expose some properties. Please see below one liner call to remove

public static function removeKeysFromAssociativeArray($associativeArray, $keysToUnset)
{
    if (empty($associativeArray) || empty($keysToUnset))
        return array();

    foreach ($associativeArray as $key => $arr) {
        if (!is_array($arr)) {
            continue;
        }

        foreach ($keysToUnset as $keyToUnset) {
            if (array_key_exists($keyToUnset, $arr)) {
                unset($arr[$keyToUnset]);
            }
        }
        $associativeArray[$key] = $arr;
    }
    return $associativeArray;
}

Call like:

removeKeysFromAssociativeArray($arrValues, $keysToRemove);
Somnath Muluk
  • 55,015
  • 38
  • 216
  • 226