2010-12-16 92 views
29

我想从基于值的多维数组中删除元素。在这种情况下,如果一个子数组的键'year'的值为2011,那么我需要这个子数组。从基于值的多维数组中删除元素

只是为了记录:我运行PHP 5.2。

我的数组是这样的:

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 
     ) 
) 

回答

60

试试这个:

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

那么你会这样称呼它:

$array = removeElementWithValue($array, "year", 2011); 
+0

我第二次选择这个。尽管Jacob解决方案非常优雅,但如果数组的嵌套级别事先已知,那么我不会打扰使用递归,如上例所示。 当然,如果事先不知道数组的结构,则必须依赖递归(或array_map与in_array或类似函数的组合,或甚至更快一些)。 – maraspin 2010-12-16 23:53:43

+0

感谢您的回复!奇妙地工作! – Bob 2010-12-17 14:28:10

+3

就在旁注:我无法得到我想要的结果。不知道我做错了什么,但我把它固定在我的情况。我不得不添加“return $ array;”在foreach循环之后,并且像这样调用它: $ array = removeElementWithValue($ array,“year”,2011); 对于将来使用此功能并希望重新排列索引的用户,可以使用以下内容: $ array = array_values($ array); – Bob 2010-12-17 18:17:09

8

试试这个:

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; 
} 
+0

多个子阵列中存在的值是多少?他们都被删除?我们可以针对基于密钥的特定子数组吗? – Luke 2017-06-08 22:47:33

4
$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); 
} 
+0

谢谢ifaour。我喜欢你的解决方案,因为我可以用这个做很多事情。我会保留这是“第二个”被接受的答案。 – Bob 2010-12-17 14:27:50

+0

@B M,第二次接受?在stackoverflow中我们有类似的东西吗?无论如何,很高兴它帮助! – ifaour 2010-12-18 10:30:29

1

对于单一的,已知的值,通过多维数组把这个迭代的开头:

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

只需跳过整个迭代,如果你的标准是正确的。

或者你也可以做相反的事情。根据口味可能更易于阅读:

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

我不知道。也许这对一些人来说看起来很尴尬。不过,我喜欢它。简短,快速和简单。

看起来像在这种情况下过滤的目的是打印出一些内容,并跳过一些,根据一定的标准。如果在循环之前执行过滤,则必须循环遍历整个事件两次 - 一次是过滤,一次是打印内容。

如果你这样做,在循环内部,这是不需要的。除了循环内部外,你也不会改变你的数组,如果你并不总是想特别按照这些标准进行过滤,这可能会有所帮助。

0

你应该试试这种方式,
$ mainArray是当前数据
$子阵列要删除

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

    var_dump(array_values($mainArray)); 

这会给你的输出你数组的新的索引想要的数据。