[英]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.