簡體   English   中英

從多維數組中遞歸刪除空元素和子數組

[英]Recursively remove empty elements and subarrays from a multi-dimensional array

我似乎找不到一個簡單直接的解決方案來解決從 PHP 中的 arrays 中刪除空元素的古老問題。

我的輸入數組可能如下所示:

Array ( [0] => Array ( [Name] => [EmailAddress] => ) ) 

(以此類推,如果有更多的數據,雖然可能沒有...)

如果它看起來像上面那樣,我希望它在我處理完之后完全是空的。

所以print_r($array); output:

Array ( )

如果我運行$arrayX = array_filter($arrayX); 我仍然得到相同print_r output。然而,我看過的所有地方都表明這是在 PHP5 中刪除空數組元素的最簡單方法。

我也試過$arrayX = array_filter($arrayX,'empty_array'); 但我收到以下錯誤:

警告:array_filter() [function.array-filter]:第二個參數“empty_array”應該是一個有效的回調

我究竟做錯了什么?

嘗試使用array_map()將過濾器應用於$array每個$array

$array = array_map('array_filter', $array);
$array = array_filter($array);

演示: http : //codepad.org/xfXEeApj

接受的答案並不完全符合 OP 的要求。 如果要遞歸刪除所有評估為 false 的值,包括空數組,請使用以下函數:

function array_trim($input) {
    return is_array($input) ? array_filter($input, 
        function (& $value) { return $value = array_trim($value); }
    ) : $input;
}

或者您可以根據需要更改退貨條件,例如:

{ return !is_array($value) or $value = array_trim($value); }

如果您只想刪除空數組。 或者您可以將條件更改為僅測試 "" 或 false 或 null 等...

有許多示例說明如何執行此操作。 您可以嘗試docs ,一個(見第一條評論)。

function array_filter_recursive($array, $callback = null) {
    foreach ($array as $key => & $value) {
        if (is_array($value)) {
            $value = array_filter_recursive($value, $callback);
        }
        else {
            if ( ! is_null($callback)) {
                if ( ! $callback($value)) {
                    unset($array[$key]);
                }
            }
            else {
                if ( ! (bool) $value) {
                    unset($array[$key]);
                }
            }
        }
    }
    unset($value);

    return $array;
}

當然,這個例子實際上並沒有使用array_filter但你明白了。

遵循 jeremyharris 的建議,這就是我需要對其進行更改以使其正常工作的方式:

function array_filter_recursive($array) {
   foreach ($array as $key => &$value) {
      if (empty($value)) {
         unset($array[$key]);
      }
      else {
         if (is_array($value)) {
            $value = array_filter_recursive($value);
            if (empty($value)) {
               unset($array[$key]);
            }
         }
      }
   }

   return $array;
}

嘗試:

$array = array_filter(array_map('array_filter', $array));

例子:

$array[0] = array(
   'Name'=>'',
   'EmailAddress'=>'',
);
print_r($array);

$array = array_filter(array_map('array_filter', $array));

print_r($array);

輸出:

Array
(
    [0] => Array
        (
            [Name] => 
            [EmailAddress] => 
        )
)

Array
(
)

默認情況下, array_filter()不是類型敏感的。 這意味着任何zero-ish 、false-y、null、空值都將被刪除。 我要遵循的鏈接將證明這一點。

OP 的樣本輸入數組是二維的。 如果數據結構是靜態的,則不需要遞歸。 對於想要從多維數組中過濾零長度值的任何人,我將提供靜態二維方法和遞歸方法。

靜態二維數組:此代碼對第 2 級元素執行“零安全”過濾器,然后刪除空子數組:( 請參閱此演示以了解此方法適用於不同(更棘手的)數組數據

$array=[
    ['Name'=>'','EmailAddress'=>'']
];   

var_export(
    array_filter(  // remove the 2nd level in the event that all subarray elements are removed
        array_map(  // access/iterate 2nd level values
            function($v){
                return array_filter($v,'strlen');  // filter out subarray elements with zero-length values
            },$array  // the input array
        )
    )
);

這是與單行代碼相同的代碼:

var_export(array_filter(array_map(function($v){return array_filter($v,'strlen');},$array)));

輸出(最初由 OP 指定):

array (
)

*如果您不想刪除空子array_filter() ,只需刪除外部array_filter()調用。


深度未知的多維數組的遞歸方法:當數組中的級別數未知時,遞歸是一種邏輯技術。 以下代碼將處理每個子數組,同時刪除零長度值和任何空子數組。 這是此代碼的演示,其中包含一些示例輸入。

$array=[
    ['Name'=>'','Array'=>['Keep'=>'Keep','Drop'=>['Drop2'=>'']],'EmailAddress'=>'','Pets'=>0,'Children'=>null],
    ['Name'=>'','EmailAddress'=>'','FavoriteNumber'=>'0']
];

function removeEmptyValuesAndSubarrays($array){
   foreach($array as $k=>&$v){
        if(is_array($v)){
            $v=removeEmptyValuesAndSubarrays($v);  // filter subarray and update array
            if(!sizeof($v)){ // check array count
                unset($array[$k]);
            }
        }elseif(!strlen($v)){  // this will handle (int) type values correctly
            unset($array[$k]);
        }
   }
   return $array;
}

var_export(removeEmptyValuesAndSubarrays($array));

輸出:

array (
  0 => 
  array (
    'Array' => 
    array (
      'Keep' => 'Keep',
    ),
    'Pets' => 0,
  ),
  1 => 
  array (
    'FavoriteNumber' => '0',
  ),
)

如果有人發現破壞了我的遞歸方法的輸入數組,請將其發布(以最簡單的形式)作為評論,我將更新我的答案。

問這個問題的時候,PHP的最新版本是5.3.10。 截至今天,現在是 8.1.1,此后發生了很多變化,一些較早的答案會提供意想不到的結果。 由於核心功能的變化,因此。 我覺得需要一個最新的答案,下面將遍歷一個數組,刪除任何空字符串、空數組或 null 的元素(因此 false 和 0 將保留),如果這導致任何更多空 arrays。它也會刪除它們。

function removeEmptyArrayElements( $value ) {
    if( is_array($value) ) {
        $value = array_map('removeEmptyArrayElements', $value);
        $value = array_filter( $value, function($v) {
            // Change the below to determine which values get removed
            return !( $v === "" || $v === null || (is_array($v) && empty($v)) );
        } );
    }
    return $value;
}

要使用它,您只需調用removeEmptyArrayElements( $array );

如果在 class 內部用作輔助方法:

private function arrayFilterRecursive(array $array): array 
{
    foreach ($array as $key => &$value) {
        if (empty($value)) {
            unset($array[$key]);
        } else if (is_array($value)) {
            $value = self::arrayFilterRecursive($value);
        }
    }

    return $array;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM