43
votes

I'm trying to delete elements from a multidimensional-array based on a value. In this case if a sub-array's key 'year' has the value 2011 I want that sub-array out.

Just for the record: i'm running PHP 5.2.

My array looks like this:

Array
(
    [0] => Array
        (
            [filmId] => 61359
            [url] => http://www.moviemeter.nl/film/61359
            [title] => Unstoppable
            [alternative_title] => 
            [year] => 2011
            [thumbnail] => http://www.moviemeter.nl/images/covers/thumbs/61000/61359.jpg
            [average] => 0
            [votes_count] => 0
            [similarity] => 100.00
            [directors_text] => geregisseerd door Richard Harrison
            [actors_text] => met Chen Shilony, Ruben Crow en David Powell
            [genres_text] => Drama / Komedie
            [duration] => 90
        )
    [1] => Array
        (
            [filmId] => 87923
            [url] => http://www.moviemeter.nl/film/87923
            [title] => Unstoppable
            [alternative_title] => 
            [year] => 2011
            [thumbnail] => http://www.moviemeter.nl/images/covers/thumbs/87000/87923.jpg
            [average] => 0
            [votes_count] => 0
            [similarity] => 100.00
            [directors_text] => geregisseerd door Example Director
            [actors_text] => met Actor 1, Actor 2 en Actor 3
            [genres_text] => Drama / Komedie
            [duration] => 90
        )
    [2] => Array
        (
            [filmId] => 68593
            [url] => http://www.moviemeter.nl/film/68593
            [title] => Unstoppable
            [alternative_title] => 
            [year] => 2010
            [thumbnail] => http://www.moviemeter.nl/images/covers/thumbs/68000/68593.jpg
            [average] => 3.3
            [votes_count] => 191
            [similarity] => 100.00
            [directors_text] => geregisseerd door Tony Scott
            [actors_text] => met Denzel Washington, Chris Pine en Rosario Dawson
            [genres_text] => Actie / Thriller
            [duration] => 98
        )
    [3] => Array
        (
            [filmId] => 17931
            [url] => http://www.moviemeter.nl/film/17931
            [title] => Unstoppable
            [alternative_title] => Nine Lives
            [year] => 2004
            [thumbnail] => http://www.moviemeter.nl/images/covers/thumbs/17000/17931.jpg
            [average] => 2.64
            [votes_count] => 237
            [similarity] => 100.00
            [directors_text] => geregisseerd door David Carson
            [actors_text] => met Wesley Snipes, Jacqueline Obradors en Mark Sheppard
            [genres_text] => Actie / Thriller
            [duration] => 96
        )
)
8

8 Answers

85
votes

Try this:

function removeElementWithValue($array, $key, $value){
     foreach($array as $subKey => $subArray){
          if($subArray[$key] == $value){
               unset($array[$subKey]);
          }
     }
     return $array;
}

Then you would call it like this:

$array = removeElementWithValue($array, "year", 2011);
9
votes

Try this:

function remove_element_by_value($arr, $val) {
   $return = array(); 
   foreach($arr as $k => $v) {
      if(is_array($v)) {
         $return[$k] = remove_element_by_value($v, $val); //recursion
         continue;
      }
      if($v == $val) continue;
      $return[$k] = $v;
   }
   return $return;
}
6
votes
$array[] = array('year' => 2010, "genres_text" => "Drama / Komedie");
$array[] = array('year' => 2011, "genres_text" => "Actie / Thriller");
$array[] = array('year' => "2010", "genres_text" => "Drama / Komedie");
$array[] = array('year' => 2011, "genres_text" => "Romance");

print_r(remove_elm($array, "year", 2010)); // removes the first sub-array only
print_r(remove_elm($array, "year", 201)); // will not remove anything
print_r(remove_elm($array, "genres_text", "drama", TRUE)); // removes all Drama
print_r(remove_elm($array, "year", 2011, TRUE)); // removes all 2011

function remove_elm($arr, $key, $val, $within = FALSE) {
    foreach ($arr as $i => $array)
            if ($within && stripos($array[$key], $val) !== FALSE && (gettype($val) === gettype($array[$key])))
                unset($arr[$i]);
            elseif ($array[$key] === $val)
                unset($arr[$i]);

    return array_values($arr);
}
2
votes

For a single, known value, put this in beginning of iteration through the multidimensional array:

foreach ( $array as $subarray ) {
  //beginning of the loop where you do things with your array
  if ( $subarray->$key == '$valueToRemoveArrayBy' ) continue;
  //iterate your stuff
}

Simply skips that entire iteration if your criteria are true.

Alternately you could do the reverse. Might be easier to read, depending on taste:

foreach ( $array as $subarray ) {
  if ( $subarray->$key != $valueToRemoveArrayBy ) {
    //do stuff 
  }
}

I dunno. Maybe this looks hacky to some. I like it, though. Short, quick and simple.

Looked like the purpose of filtering in this case was to print out some contents and skip some, based on certain criteria. If you do the filtering before the loop, you'll have to loop through the entire thing twice - once to filter and once to print the contents.

If you do it like this, inside the loop, that is not required. You also won't alter your array except for inside of the loop, which can be helpful if you don't always want to filter by these criteria in particular.

1
votes
function removeElementWithValue($array, $value){
    $temp=array(); //Create temp array variable.
    foreach($array as $item){ //access array elements.
        if($item['year'] != $value){ //Skip the value, Which is equal.
        array_push($temp,$item);  //Push the array element into $temp var.
        }
     }
     return $temp; // Return the $temp array variable.
}

//Simple code to delete element of multidimensional array.
$array = removeElementWithValue($array, "year");
0
votes

You should try this way,
$mainArray is your current data
$subArray is the data you want to remove

    foreach ($mainArray as $key => $mainData){
        foreach ($subArray as $subData){
            if($mainData['dataId'] == $subData['dataId']){
                unset($mainArray[$key]);
                break;
            }
        }
    }

    var_dump(array_values($mainArray));

This will give you output you wanted with new index of array.

0
votes

This is how I achieved it:

<?php 
    print_r($array);
    echo "<br><br>";
    foreach($array as $k => $v){
        echo "k: ".$k." v: ".$v."<br><br>";
        if(($v == 'Toronto') || ($v == 'London')){
            unset($array[$k]);
        }
    }
    echo "<br><br>";
    print_r($array);
?>
0
votes

Here is my approach to this problem: use array_udiff with custom function to (un-)match 'year' from one array's elements to the elements of the "filter" array.

function fn_year_filter($a, $b) {
    return (is_array($a) ? $a['year'] : $a) != (is_array($b) ? $b['year'] : $b);
}
$array = array_udiff($array, array('2011', '2020'), 'fn_year_filter');

And even simpler with the anonymous functions of PHP > 5.3

$array = array_udiff($array, array(2011, 2020), function($a, $b) {
    return (is_array($a) ? $a['year'] : $a) != (is_array($b) ? $b['year'] : $b);
});

* Note the use of loose comparison, hence it works with integers too.