我需要删除多级数组上的空条目。现在我可以删除带有空子数组的条目,但不能删除空数组...很困惑,我也是...我认为代码将有助于更好地解释。
/**
*
* This function remove empty entries on arrays
* @param array $array
*/
function removeEmptysFromArray($array) {
$filtered = array_filter($array, 'removeEmptyItems');
return $filtered;
}
/**
*
* This is a Callback function to use in array_filter()
* @param array $item
*/
function removeEmptyItems($item) {
if (is_array($item)) {
return array_filter($item, 'removeEmptyItems');
}
if (!empty($item)) {
return true;
}
}
$raw = array(
'firstname' => 'Foo',
'lastname' => 'Bar',
'nickname' => '',
'birthdate' => array(
'day' => '',
'month' => '',
'year' => '',
),
'likes' => array(
'cars' => array('Subaru Impreza WRX STi', 'Mitsubishi Evo', 'Nissan GTR'),
'bikes' => array(),
),
);
print_r(removeEmptysFromArray($raw));
此代码将删除
nickname
、birthdate
,但不会删除具有空数组的 bikes
。
我的问题是...如何删除
bikes
条目?
试试这个代码:
<?php
function array_remove_empty($haystack)
{
foreach ($haystack as $key => $value) {
if (is_array($value)) {
$haystack[$key] = array_remove_empty($haystack[$key]);
}
if (empty($haystack[$key])) {
unset($haystack[$key]);
}
}
return $haystack;
}
$raw = array(
'firstname' => 'Foo',
'lastname' => 'Bar',
'nickname' => '',
'birthdate' => array(
'day' => '',
'month' => '',
'year' => '',
),
'likes' => array(
'cars' => array('Subaru Impreza WRX STi', 'Mitsubishi Evo', 'Nissan GTR'),
'bikes' => array(),
),
);
print_r(array_remove_empty($raw));
这是我的解决方案,它将递归地删除精确指定的空值列表:
/**
* Remove elements from array by exact values list recursively
*
* @param array $haystack
* @param array $values
*
* @return array
*/
function array_remove_by_values(array $haystack, array $values)
{
foreach ($haystack as $key => $value) {
if (is_array($value)) {
$haystack[$key] = array_remove_by_values($haystack[$key], $values);
}
if (in_array($haystack[$key], $values, true)) {
unset($haystack[$key]);
}
}
return $haystack;
}
你可以这样使用它:
$clean = array_remove_by_values($raw, ['', null, []]);
注意,如果您将
[]
作为值之一传递,它会删除空子数组。
array_filter(explode('/', '/home/teste sdsd/ /'), 'trim');
//Result
[
1 => "home",
2 => "teste sdsd",
]
//-----------
array_filter(explode('/', '/home/teste sdsd/ /'), 'strlen')
//Result
[
1 => "home",
2 => "teste sdsd",
3 => " ",
]
我认为这应该可以解决你的问题。
$retArray =array_filter($array, arrayFilter);
function arrayFilter($array) {
if(!empty($array)) {
return array_filter($array);
}
}
递归清除空项的多维数组:
final class ArrayCleaner
{
public static function clean(array $value): array
{
foreach ($value as $k => $v) {
if (\is_array($v)) {
$value[$k] = self::clean($v);
if (0 == \count($value[$k])) {
unset($value[$k]);
}
} elseif (empty($v)) {
unset($value[$k]);
}
}
return $value;
}
}
单元测试:
final class ArrayCleanerTest
{
public function testItCleans(): void
{
$input = [
'empty_string_to_remove' => '',
'empty_int_to_remove' => 0,
'empty_string_number_to_remove' => '0',
'value_to_keep' => 5,
'empty_array_to_remove' => [],
'empty_array_of_empty_arrays_to_remove' => [
'one' => [],
'two' => [],
'three' => [false, null, '0'],
],
'array_to_keep_1' => [
'value' => 1,
],
'array_to_keep_2' => [
'empty_to_remove' => [],
'array_to_keep' => ['yes'],
],
];
$expected = [
'value_to_keep' => 5,
'array_to_keep_1' => [
'value' => 1,
],
'array_to_keep_2' => [
'array_to_keep' => ['yes'],
],
];
$this->assertEquals($expected, ArrayCleaner::clean($input));
}
}
基于递归函数的简单而优雅的解决方案。不喜欢上一个解决方案。答案。删除空子数组/子值:
/**
* Clean array from empty values
* @param $array
* @return array|mixed
*/
function array_filter_recursive($array){
if (!is_array($array)) return $array;
foreach ( $array as $key=>$item){
if (is_array($item))
$array[$key] = array_filter_recursive($item);
}
return array_filter($array);
}
array_filter()
和 empty()
对于提问者的样本输入来说可能是安全的,但它们对于公众一般用途来说并不可靠。这些本机函数会将所有“错误”值视为可过滤/空。有关其贪婪确定空性的详细信息,请参阅 empty()
的文档。
我建议显式检查(特别是数据类型)是否有空字符串(如果这是意图)。这样您就不会无意中破坏有意义的数据。我选择将 $value
声明为引用以避免迭代数组的副本 - 这允许我使用
$value
而不是更详细的
$array[$key]
来改变/覆盖数组数据(当不使用
unset()
时)。代码:(
带有各种错误值的演示)
function recursivelyRemoveEmpties(array $array): array
{
foreach ($array as $key => &$value) {
if (is_array($value)) {
$value = recursivelyRemoveEmpties($value);
if (!$value) {
unset($array[$key]);
}
continue;
}
if ($value === '') {
unset($array[$key]);
}
}
return $array;
}
var_export(recursivelyRemoveEmpties($raw));
*请注意,此脚本并非旨在容纳数据有效负载中的对象。
function removeEmptyItems($item)
{
if (is_array($item)) {
$item = array_filter($item, 'removeEmptyItems');
}
return !empty($item);
}
$nonEmpty = array_filter($raw, 'removeEmptyItems');
function removeEmptyItems(&$item) {
if (is_array($item) && $item) {
$item = array_filter(&$item, 'removeEmptyItems');
}
return !!$item;
}