2016-05-05 3 views
1

Могу ли я и как я могу использовать PHP array_filter для фильтрации записей пустых/нулей из следующей структуры массива?PHP Array_filter на «простом» многоуровневом массиве

От: Массив от вызова PDO с использованием Fetch BOTH, поэтому числовые и именованные значения всегда равны в этом случае.

Array 
(
    [2400] => Array 
     (
      [0] => Array 
       (
        [value] => 7 
        [0] => 7 
       ) 
      [1] => Array 
       (
        [value] => 61 
        [0] => 61 
       ) 
      [2] => Array 
       (
        [value] => 42 
        [0] => 42 
       ) 
      [3] => Array 
       (
        [value] => 
        [0] => 
       ) 
     ) 
) 

To:

Array 
(
    [2400] => Array 
     (
      [0] => Array 
       (
        [value] => 7 
        [0] => 7 
       ) 
      [1] => Array 
       (
        [value] => 61 
        [0] => 61 
       ) 
      [2] => Array 
       (
        [value] => 42 
        [0] => 42 
       ) 
     ) 
) 

Я попытался

  • простой старый array_filter
  • array_filter(array, function($f){ ??? }) и не совсем уверен, куда идти отсюда ... Я собирался foreach массив, чтобы вникать в него, но как это повлияет на записи через array_filter ? Не вернет ли истинный/ложный доход весь массив [2400]? Это просто меня смущает.

Пожалуйста, предложить меры по улучшению вопроса

+0

dod вы хотите удалить antry с любым нулевым или обоими? – splash58

+0

любой пустой или нулевой нормальный критерий, который вычисляет значение «false» –

+0

, вы можете использовать 'array_map' для просмотра и удаления пустого массива. –

ответ

2

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

Например, элемент основного массива с индексом 2400 должен быть включен в результирующий набор, но его содержимое должно быть изменено.

Я написал простую функцию для этого, надеюсь, что это может помочь. Ну, вы можете использовать это для вдохновения. И это было интересным вызовом для меня.

Ниже приведена моя функция с проверкой пары.

<?php 

function deepFilter(array $array) 
{ 
    // Formally this is not need because if array is empty then $filteredArray will also be empty 
    // but it simplifies the algorithm 
    if (empty($array)) { 
     return []; 
    } 

    $filteredArray = []; 
    foreach ($array as $key => $value) { 
     if (is_array($value) && !empty($value)) { 
      $value = deepFilter($value); 
     } 
     if (!empty($value)) { 
      $filteredArray[$key] = $value; 
     } 
    } 

    return $filteredArray; 
} 

$testArray1 = [ 
    2400 => [ 
     0 => [ 
      'value' => 7, 
      0 => 7, 
     ], 
     1 => [ 
      'value' => 61, 
      0 => 61, 
     ], 
     2 => [ 
      'value' => 42, 
      0 => 42, 
     ], 
     3 => [ 
      'value' => null, 
      0 => null, 
     ] 
    ] 
]; 

$testArray2 = [ 
    2400 => [ 
     0 => [ 
      'value' => 7, 
      0 => 7, 
     ], 
     1 => [ 
      'value' => 61, 
      0 => 61, 
     ], 
     2 => [ 
      'value' => 42, 
      0 => 42, 
     ], 
     3 => null 
    ], 
    3243 => [ 
     0 => [ 
      'value' => 7, 
      0 => null, 
     ], 
     1 => [ 
      'value' => null, 
      0 => 61, 
     ], 
     2 => [ 
      'value' => 42, 
      0 => 42, 
     ], 
     3 => null 
    ] 
]; 
var_export(deepFilter($testArray1)); 
var_export(deepFilter($testArray2)); 

Идея очень проста.

  1. Возьмите массив и проверьте элементы один за другим.
  2. Если элемент представляет собой массив, примените функцию для этого элемента и проверьте результат. Мы можем удалить все из дочернего массива, и в этом случае мы не должны добавлять его к результатам. Если у ребенка есть что-то, оставшееся после очистки, включите «очищенный ребенок» в наш результирующий набор.
  3. Если наш элемент не является массивом, включите его, только если он не пуст.

Пожалуйста, дайте мне знать, если вы обнаружите ошибки или работает для вас или нет.

+0

Да, это была проблема, с которой я столкнулся, в то время как вы пытались изложить предложения в других ответах. Это даст мне пустые массивы, а не полностью исключает эту клавишу. Я создал свою собственную функцию, чтобы перебирать массив и проверять элементы один за другим, и это работало именно так, как мне было нужно. Я верю, что вы ответили на мой вопрос лучше всего: «Будет ли array_filter работать для этого» –

1

Использование array_filter и проверить value элемент (или 0 элемент, так как они эквивалентны).

$array[2400] = array_filter($array[2400], function($element) { 
    return $element['value']; 
}); 

Для того, чтобы сделать это для всех элементов внешнего массива, используйте foreach петлю.

foreach ($array as &$subarray) { 
    $subarray = array_filter($subarray, function($element) { 
     return $element['value']; 
    }); 
} 

или array_map:

$array = array_map(function($subarray) { 
    return array_filter($subarray, function($element) { 
     return $element['value']; 
    }); 
}, $array); 
+0

hmm .. ключ «2400» является переменной и может изменение. –

+0

Итак, петля над всеми элементами массива. – Barmar

1

Если структура массива остается неизменным, то это должно работать:

foreach ($array as &$innerArray) { 
    $innerArray = array_filter($innerArray, function($arr) { 
     return (!empty($arr[0])); 
    }); 
} 
unset($innerArray);