2010-12-16 91 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)); 

這會給你的輸出你數組的新的索引想要的數據。