Как удалить пустые значения из многомерного массива в PHP?

Я искал много ответов, но ни один из них не работает для меня.

это данные, присвоенные my $quantities время:

Array(
    [10] => Array([25.00] => 1)
    [9] => Array([30.00] => 3)
    [8] => Array([30.00] => 4)
    [12] => Array([35.00] => )
    [1] => Array([30.00] => )
    [2] => Array([30.00] => )
)

Я ищу способ, чтобы удалить подмассивы с пустыми значениями, как [12] [1] и [2] сохраняя все остальное.

желаемый результат:

Array(
    [10] => Array([25.00] => 1)
    [9] => Array([30.00] => 3)
    [8] => Array([30.00] => 4)
)

Я пробовал много функций в официальных документах php, и ни одна из них не работала.

я использовал этот один:

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(
    [10] => Array([25.00] => 1)
    [9] => Array([30.00] => 3)
    [8] => Array([30.00] => 4)
    [12] => Array()
    [1] => Array()
    [2] => Array()
)

8 ответов


немного поздно, но может помочь кому-то, кто ищет тот же ответ. Я использовал этот очень простой подход к работе;

  1. удалите все ключи из вложенных массивов, которые не содержат значения, затем
  2. удалить все пустые вложенные массивы.

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

следующая функция работала для моего случая. Мы можем использовать простую рекурсивную функцию для удаления всех пустых элементов из многомерного массива PHP:

function array_filter_recursive($input){
    foreach ($input as &$value){
        if (is_array($value)){
            $value = array_filter_recursive($value);
        }
    }
    return array_filter($input);
}

Затем нам просто нужно вызвать эту функцию:

$myArray = array_filter_recursive($myArray);

Не уверен, что это именно то, что ищете.

function array_remove_null($array) {
    foreach ($array as $key => $value)
    {
        if(is_null($value))
            unset($array[$key]);
        if(is_array($value))
            $array[$key] = array_remove_null($value);
    }
    return $array;
}

обновление (исправления):

function array_remove_null($array) {
    foreach ($array as $key => $value)
    {
        if(is_null($value))
            unset($array[$key]);
        if(is_string($value) && empty($value))
            unset($array[$key]);
        if(is_array($value))
            $array[$key] = array_remove_null($value);
        if(isset($array[$key]) && count($array[$key])==0)
            unset($array[$key]);
    }
    return $array;
}

Я уверен, что лучше проверить и сделать это более надежным может помочь решению.


используйте array_map () для фильтрации каждого массива в $array:

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

здесь демо


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

это sintax это работа и очень помогает полное спасибо ребятам ..


использовать array_filter С array_map, как показано ниже:

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

это удаляет все элементы с нулевыми значениями рекурсивно на многодеминсионных массивах. Работает на PHP >= 5.6. Если вы хотите удалить все значения "empry", замените !is_null($value) С !empty($value).

function recursivelyRemoveItemsWithNullValuesFromArray(array $data = []): array
{
    $data = array_map(function($value) {
        return is_array($value) ? recursivelyRemoveItemsWithNullValuesFromArray($value) : $value;
    }, $data);

    return array_filter($data, function($value) {
        return !is_null($value);
    });
}

поскольку подзоны в вашем массиве имеют только один элемент каждый, вы можете упростить подход, используя любой из двух следующих методов. Логическое преимущество заключается в том, чтобы избежать функционального итератора (array_filter) на втором уровне элементов. Вот почему current() больше подходит для этого вопроса/страница.

код: (демо)

$quantities=[
    10=>['25.00'=>1],
    9=>['30.00'=>3],
    8=>['30.00'=>4],
    12=>['35.00'=>null],
    1=>['30.00'=>''],
    2=>['30.00'=>null]
];

var_export(array_filter($quantities,function($a){return strlen(current($a));}));

или

foreach($quantities as $key=>$sub){  // could be done "by reference" but that impacts code stability
    if(!strlen(current($sub))){  // if subarray value has no length
        unset($quantities[$key]);
    }
}
var_export($quantities);

как выходной один и тот же результат (который намеренно удаляет пустые значения и варенье 0 значение)

array (
  10 => 
  array (
    '25.00' => 1,
  ),
  9 => 
  array (
    '30.00' => 3,
  ),
  8 => 
  array (
    '30.00' => 4,
  ),
)

в вышеуказанных методах,strlen() используется для проверки элементов 2-го уровня, потому что OP только перечисленные целые числа как "непустые" значения. Будущее поэтому читатели могут иметь различные требования, основанные на элементах, возможно проведение false, null, '0', 0, etc. Подходящие функции замены для strlen() может быть: любой функции "is_", пустая(), ни функции "ctype", и многое другое.

если массив 2-го уровня OP содержал более одного элемента, и OP хотел удалить все нуль-иш, false-y, пустые, нулевые элементы (то есть нули не нужны или гарантированно не происходят), то Alastair f's answer было бы лучшим выбором.

если входной массив OP имел неизвестное количество уровней и нулевые/false-y/empty / null элементы должны быть удалены, то ответ Резы Мамуна - это логическое, рекурсивное подход.

моя точка зрения (и моя мотивация за тратить так много времени и заботы, чтобы ответить на этот вопрос), что array_filter() является жадным, и если вы не знаете об этом поведении по умолчанию, ваш проект может молча выводить неправильную информацию. Надеюсь, это объяснение сэкономит программистам время и силы.