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

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

Это данные, присваиваемые моему массиву $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()
)

Ответ 1

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

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

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

Ответ 2

В моем случае работала следующая функция. Мы можем использовать простую рекурсивную функцию для удаления всех пустых элементов из многомерного массива 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);

Ответ 3

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

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

Забастовкa >

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

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

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

Ответ 4

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

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

Здесь демонстрация

Ответ 5

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

Этот синтакс, который он работает, и очень помог полностью поблагодарить ребят..

Ответ 6

Используйте array_filter с array_map, как показано ниже:

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

Ответ 7

Это удаляет все элементы с нулевыми значениями рекурсивно на многопользовательских массивах. Работает на 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);
    });
}

Ответ 8

Поскольку у подмассивов в вашем массиве есть только один элемент, вы можете упростить подход, используя любой из двух следующих методов. Логическое преимущество заключается в том, чтобы избежать функционального итератора (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-го уровня, поскольку только ОП перечисляет целые числа как "непустые" значения. У будущих читателей SO могут быть разные требования, основанные на элементах, возможно содержащих false, null, '0', 0 и т.д. Подходящими функциями замены для strlen() могут быть: любой из функции "is_" , empty(), любой из функции "ctype" и многое другое.

Если массив 2-го уровня OP удерживал более одного элемента, и OP хотел удалить все нулевые, ложные-y, пустые, нулевые элементы (что означает, что нули не нужны или не гарантируются), тогда Ответ Alastair F будет лучшим выбором.

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

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