2012-04-18 4 views
10

Я искал много ответов, но никто из них не работает для меня.Как удалить пустые значения из многомерного массива в 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() 
) 
+0

Рассмотрите возможность использования var_dump(), чтобы показать нам содержимое массива. –

+0

Для страницы, используемой в качестве места назначения для стольких ссылок на дублирование, эта страница имеет удивительное количество исправленных неверных ответов. @ Richard-MX Я опубликовал ответ, который не использует рекурсию или несколько функций итерации, так что читатели, которые становятся жертвами торговли, могут увидеть плохое рабочее (нулевое) решение. (непонятно в вашем сообщении, если ваши пустые массивы имеют пустые строки или «null» в качестве значений, поэтому я продемонстрировал их оба) – mickmackusa

ответ

12

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

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

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

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

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

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

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

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

+0

Здравствуйте, Джейсон, спасибо за ваш ответ. К сожалению, он не работает для того, что мне нужно.Как отвечает Пол, он возвращает то же, что и исходный вопрос. –

+0

Я не уверен, почему у этого есть 4 upvotes. Этот код-единственный ответ не работает. [Demo] (http://sandbox.onlinephpfunctions.com/code/a06f86d99043713158cb6170b516ffebd9533f4a) – mickmackusa

+0

@mickmackusa Этот пример работал во времена PHP 5. –

1

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

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

Вот demo

+0

Этот ответ НЕ РАБОТАЕТ. Он не работает в опубликованной демонстрационной ссылке. Он не работает в [моей демонстрационной ссылке] (http://sandbox.onlinephpfunctions.com/code/e8b7659f6b504afea691451351c039de24c0a7f4) Как в мире это заработало 3 upvotes? Сдвиньте от меня. – mickmackusa

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

Это синтаксис это работа и очень помогает ребятам ПОЛНОГО THANK в ..

+0

Это точный дубликат метода (характер для символа) ответа Найтикаша, который был опубликован двумя месяцами ранее. Если вы не можете улучшить свой ответ, чтобы предоставить лучшую информацию, вы должны удалить этот ответ, потому что он не добавляет значения для страницы (это просто раздутие страницы). – mickmackusa

+0

Этот ответ НЕ РАБОТАЕТ. Он не работает в [моей демонстрационной ссылке] (http://sandbox.onlinephpfunctions.com/code/e8b7659f6b504afea691451351c039de24c0a7f4) Как в мире это заработало 3 upvotes? Сдвиньте от меня. – mickmackusa

5

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

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

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

Это не новая информация. Это дубликат ответа [AlastairF] (https://stackoverflow.com/a/18796083/2943403), написанного как однострочный. – mickmackusa

-1

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

+0

Этот ответ не обеспечивает желаемый выход OP. [Демо] (http://sandbox.onlinephpfunctions.com/code/c30daafe3cf0959e0a0c4dcaa901244605a8f7d9) – mickmackusa

-2

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

Код: (Demo)

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

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

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

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