Can I and how can I use PHP's array_filter
to filter the blank/nulls entries out of the following array structure?
From: The array is from a PDO call using Fetch BOTH so the numeric and named values are always equal in this case.
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
)
)
)
I have tried
array_filter
array_filter(array, function($f){ ??? })
and not quite sure where to go from here... I was going to foreach the array to delve into it but how will that affect the entries through array_filter
? Won't a true/false return bring in the entire [2400] array portion? It just has me confused.Please suggest improvements to the question
Use array_filter
and test the value
element (or the 0
element, since they're equivalent).
$array[2400] = array_filter($array[2400], function($element) {
return $element['value'];
});
To do it for all elements of the outer array, use a foreach
loop.
foreach ($array as &$subarray) {
$subarray = array_filter($subarray, function($element) {
return $element['value'];
});
}
or array_map
:
$array = array_map(function($subarray) {
return array_filter($subarray, function($element) {
return $element['value'];
});
}, $array);
I think this can not be done using only array_filter
function because sometimes you need to modify array elements but the array_filter
function allows only to decide if the element should be excluded or not.
For example in the main array element with index 2400 should be included in the result set but it's content should be modified.
I wrote a simple function to do this, hope it might help. Well, you might use this for inspiration. And it was interesting challenge for me as well.
Below is my function with couple tests.
<?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));
The idea is very simple.
Please let me know if you find any mistakes or if it works for you or not.
If the array structure stays the same then this should work:
foreach ($array as &$innerArray) {
$innerArray = array_filter($innerArray, function($arr) {
return (!empty($arr[0]));
});
}
unset($innerArray);
You can concisely filter the subset data by making iterated calls of array_filter()
via array_map()
. You can avoid writing a custom function for array_filter()
by calling the native function array_sum()
(or array_product()
) -- this yields the correct truthy/falsey result because any data set with nulls will be calculated as 0
, and everything else with be non-zero ("truthy").
Code: ( Demo )
var_export(
array_map(fn($row) => array_filter($row, 'array_sum'), $array)
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.