【问题标题】:Delete element from multidimensional-array based on value根据值从多维数组中删除元素
【发布时间】:2011-05-26 20:30:19
【问题描述】:

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

【问题讨论】:

    标签: php arrays multidimensional-array


    【解决方案1】:

    试试这个:

    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 或类似函数的组合,甚至可以更快一些)。
    • 只是在旁注:我无法得到我想要的结果。不知道我做错了什么,但我在我的情况下修复了它。我不得不添加“return $array;”在 foreach 循环之后,像这样调用它: $array = removeElementWithValue($array, "year", 2011);对于以后使用这个并且想要重新排列索引的人,可以使用如下:$array = array_values($array);
    • 对我很有用。 注意: 这不会改变数组索引。示例:如果您的数组有 2 项(索引为 0 和 1),并且您删除了第一项(k = 0),那么数组将只有索引 1(k = 1),因此不会替换索引作为索引 0。
    【解决方案2】:

    试试这个:

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

    【讨论】:

    • 多个子数组中存在什么相同的值?他们都被删除了?我们可以根据键定位特定的子数组吗?
    • 这个答案缺少教育解释。
    【解决方案3】:
    $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);
    }
    

    【讨论】:

    • 谢谢你。我确实喜欢您的解决方案,因为我可以用它做很多事情。我会保持这是“第二个”接受的答案。
    • @B M,第二个接受了吗?我们在stackoverflow中有类似的东西吗?无论如何,很高兴它有帮助!
    【解决方案4】:

    对于单个已知值,将其放在多维数组的迭代开始处:

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

    我不知道。也许这对某些人来说看起来很老套。不过我喜欢。简短、快速、简单。

    看起来在这种情况下过滤的目的是根据某些标准打印出一些内容并跳过一些内容。如果你在循环之前进行过滤,你将不得不循环整个事情两次——一次过滤,一次打印内容。

    如果你这样做,在循环内,这不是必需的。除了循环内部之外,您也不会更改您的数组,如果您不总是特别想根据这些条件进行过滤,这会很有帮助。

    【讨论】:

      【解决方案5】:
      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");
      

      【讨论】:

        【解决方案6】:

        你应该试试这个方法,
        $mainArray 是您当前的数据
        $subArray 是你要删除的数据

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

        这将为您提供带有新数组索引的输出。

        【讨论】:

          【解决方案7】:

          这就是我实现它的方式:

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

          【讨论】:

            【解决方案8】:

            这是我解决这个问题的方法:使用 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);
            });
            

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-09-18
              • 1970-01-01
              • 1970-01-01
              • 2012-04-27
              • 2017-04-11
              • 1970-01-01
              相关资源
              最近更新 更多