基于值从多维数组中删除元素

50

我试图根据某个值从多维数组中删除元素。在这种情况下,如果子数组的键 '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
        )
)
7个回答

99

试试这个:

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

然后你会这样称呼它:
$array = removeElementWithValue($array, "year", 2011);

我同意这个选择。虽然Jacob的解决方案非常优雅,但如果数组的嵌套级别事先已知,我不会费心使用递归,就像上面显示的示例一样。当然,如果数组的结构事先未知,你必须依赖递归(或array_map与in_array或类似函数的组合,这甚至可能会更快)。 - maraspin
4
顺便说一下:我没有得到想要的结果。不确定我做错了什么,但在我的情况下我进行了修复。我必须在foreach循环后添加“return $array;”,并像这样调用它: $array = removeElementWithValue($array, "year", 2011);对于将来使用并且想要重新排列索引的人,您可以使用以下内容: $array = array_values($array); - Bob
对我很有用。注意:这不会更改数组索引。例如:如果您的数组有2个项目(索引为0和1),并且您删除了第一个项目(k = 0),那么该数组将仅具有索引1(k = 1),因此该索引将不会被替换为索引0。 - Jimmy Adaro

10

试试这个:

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

同一个值存在于多个子数组中,它们都会被移除吗?我们能否基于键值定位特定的子数组? - Luke
2
此回答缺少教育性的解释。 - mickmackusa

6
$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);
}

3

如果需要在多维数组的迭代开始时添加一个已知值,请将其放置在开头:

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

我不知道。对于一些人来说,也许这看起来有点hacky(笨拙)。不过我喜欢它,因为短小、快速而且简单。

在这种情况下,过滤的目的是基于某些条件打印某些内容并跳过某些内容。如果您在循环之前进行过滤,那么就必须循环两次 - 一次进行过滤,一次打印内容。

如果您像这样在循环内部进行操作,则不需要进行上述操作。此外,除了循环内部以外,您也不会修改数组,这对于您不总是想按特定标准进行筛选非常有帮助。


2
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

这是我实现它的方法:

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

注意:我的回答与driangle发送的回答有何不同?像NiDBiLD和Abdulrazzak Jakati提供的回答一样,我的解决方案与最佳答案中所选择的方案非常相似。然而,个性化实现上存在差异,这对于读者全面理解解决方案可能是有用的。我的解决方案已应用于一个真实项目,并保证能够正常工作。它不仅是一个原型,而且确切地可以正常工作。请同时查看NiDBiLD和Abdulrazzak Jakati的解决方案,它们与最佳答案中的解决方案非常相似,但仍为读者增加了价值。

0
这是我的解决方案:使用{{link1:array_udiff}}和自定义函数来将一个数组的“年份”与“过滤器”数组的元素进行(不)匹配。
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');

使用 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);
});

* 请注意使用宽松比较,因此它也适用于整数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接