删除空数组元素


783

根据用户提交的内容,数组中的某些元素是空字符串。我需要删除那些元素。我有这个:

foreach($linksArray as $link)
{
    if($link == '')
    {
        unset($link);
    }
}
print_r($linksArray);

但这是行不通的。$linksArray仍然有空元素。我也尝试过使用该empty()功能,但是结果是一样的。


1
我认为值得一提的是,上面的代码不起作用,因为unset(...)对由foreach循环创建的变量进行操作,而不是对循环之前保持原样的原始数组进行操作。
saveario

if(!empty($ link)){echo $ link; }这对我
有用

U正在更改未引用的$ link!使用foreach($ linksArray as $ key => $ link)unset(linksArray [$ key])
TD_Nijboer

Answers:


1547

在处理字符串数组时,您可以简单地使用array_filter(),它可以方便地为您处理所有这一切:

print_r(array_filter($linksArray));

请记住,如果未提供回调,则将删除所有等于FALSE(请参见转换为boolean)的数组项。因此,如果您需要保留元素,即确切的string '0',则需要一个自定义回调:

// PHP 7.4 and later
print_r(array_filter($linksArray, fn($value) => !is_null($value) && $value !== ''));

// PHP 5.3 and later
print_r(array_filter($linksArray, function($value) { return !is_null($value) && $value !== ''; }));

// PHP < 5.3
print_r(array_filter($linksArray, create_function('$value', 'return $value !== "";')));

16
array_filter应该删除空元素。而且,如果PHP的empty定义与您的定义不太相同,那么您可以使用一个匿名函数来填充callback选项,该函数会抛出不需要的元素。显然,您必须具有php 5.3或更高版本才能使用匿名回叫。stackoverflow.com/questions/2412299/...
巴特尔布特库斯

76
注意array_filter不会重新索引数组索引(在for语句中使用进程数组可能会出现问题)。因此,请使用array_values函数包装所有内容。
米哈尔-阿雷达网

8
答案是错误的,因为它也会删除false元素。(php.net/manual/en/function.array-filter.php
pliashkou

5
@Deji您是否尝试过在过滤之前打印该数组?我认为a第二次设置只会重置第一个。
Cullub '16

5
@Cranio:已经被另一条评论所覆盖。这不是不正确,但也许更广泛的你的要求。这并不意味着其他人仍然找不到帮助。毕竟,如果您只有数组中的字符串,那么此答案将仅删除空字符串。
马丁·彼得斯

169

您可以array_filter用来删除空元素:

$emptyRemoved = array_filter($linksArray);

如果(int) 0阵列中有,则可以使用以下命令:

$emptyRemoved = remove_empty($linksArray);

function remove_empty($array) {
  return array_filter($array, '_remove_empty_internal');
}

function _remove_empty_internal($value) {
  return !empty($value) || $value === 0;
}

编辑:也许您的元素本身并不为空,但包含一个或多个空格...您可以在使用之前使用以下内容array_filter

$trimmedArray = array_map('trim', $linksArray);

10
我只是将其添加到BoltClock接受的答案中,您可以简单地执行array_filter($ foo,'strlen')以避免出现“ 0”问题,而只删除长度为零的那些。
AB Carroll

2
@nezZario:假设您scalar的数组中只有项目,是的。否则,您将无法做到。
Andrew Moore

2
使用lambda for php> = 5.3function remove_empty($array) { return array_filter($array, function($value){return !empty($value) || $value === 0;}); }
病毒式的病毒

1
array_map()魔术角色我在那些空数组中有空格!
神童

126

关于此主题的最流行答案是绝对不正确。

考虑以下PHP脚本:

<?php
$arr = array('1', '', '2', '3', '0');
// Incorrect:
print_r(array_filter($arr));
// Correct:
print_r(array_filter($arr, 'strlen'));

为什么是这样?因为包含单个“ 0”字符的字符串也将计算为布尔值false,所以即使它不是一个空字符串,也仍然会被过滤。那将是一个错误。

将内置的strlen函数用作过滤函数将起作用,因为它将为非空字符串返回一个非零整数,为一个空字符串返回一个零整数。非零整数在转换为布尔值时始终求值为true,而零整数在转换为布尔值时始终求值为false。

因此,绝对,确定,正确的答案是:

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

3
同意 对于那些数组包含字符串的用户,这应该是公认的答案
mwieczorek

2
已投票。一个比其他答案更好的答案,但是应该注意,当前接受的答案在技术上并不是错误的,因为“空”确实在PHP中具有特殊含义。(有资格作为一些值“空”: ,0,)""null
rinogo

5
它们不是不正确的,而是关于上下文的。在某些情况下,保留值0可能很重要。因此,请不要说每个人都错了,只有你
Macr1408 '18

6
如果该数组包含另一个数组strlen() expects parameter 1 to be string, array given
则会

您可以说这也是实现自己期望的动作的一种好方法(而不是说其他​​人不正确)。基本上并非所有情况都是相似的。
MR_AMDEV

102
$linksArray = array_filter($linksArray);

“如果未提供回调,则将删除所有等于FALSE的输入项。” - http://php.net/manual/en/function.array-filter.php


4
Google'ing问题之后,我也尝试了此操作。不幸的是,它为我留下了空白。
威尔

18
这也会删除“ 0”
OIS

2
@Will:你确定吗?它也删除了空字符串,我已经成功测试过了。也许您的输入值包含空格,应该在之前进行修剪。根据布尔转换规则,空字符串被评估为false,因此被array_filter删除。
acme

52
    $myarray = array_filter($myarray, 'strlen');  //removes null values but leaves "0"
    $myarray = array_filter($myarray);            //removes all null values

strlen还删除了false :(
justnorris 2014年

42

你可以做

array_filter($array)

array_filter:“如果未提供回调,则将删除所有等于FALSE的输入项。” 这意味着值NULL,0,'0','',FALSE,array()的元素也将被删除。

另一个选择是做

array_diff($array, array(''))

这将删除值为NULL,''和FALSE的元素。

希望这可以帮助 :)

更新

这是一个例子。

$a = array(0, '0', NULL, FALSE, '', array());

var_dump(array_filter($a));
// array()

var_dump(array_diff($a, array(0))) // 0 / '0'
// array(NULL, FALSE, '', array());

var_dump(array_diff($a, array(NULL))) // NULL / FALSE / ''
// array(0, '0', array())

总结一下:

  • 0或'0'将删除0和'0'
  • NULL,FALSE或''将删除NULL,FALSE和''

36
foreach($linksArray as $key => $link) 
{ 
    if($link === '') 
    { 
        unset($linksArray[$key]); 
    } 
} 
print_r($linksArray); 

4
简洁,易读且安全的解决方案,不会删除false0。考虑到这是与接受答案的同一分钟发布(那是不安全且不正确的),因此我只能假设您的8次投票与接受答案的649相较于后者是单行解决方案。
rybo111 '16

@ rybo111-可能,尽管在回调中使用该逻辑array_filter()foreach()循环更清洁
Mark Ba​​ker

也许更快,但是您的解决方案最易读,这很重要。对于使用您的解决方案的用户trim(),我建议if(is_string($link) && trim($link) === '')
rybo111 '16

33

另一个衬里用于从数组中删除空(“空字符串”)元素。

$array = array_filter($array, function($a) {return $a !== "";});

注:此代码刻意保持null0false元素。


或者,也许您想先修剪数组元素:

$array = array_filter($array, function($a) {
    return trim($a) !== "";
});

注意:此代码还会删除nullfalse元素。


3
正是我所需要的,这也与旧的PHP兼容,谢谢!;-)
Stano

1
@JohnK错误。要做到这一点酷似用户whants回调必要,除非你想删除alzo零和其他falsey值。
克拉尼奥2015年

哦,这绝对是可爱的。应该是被接受的。
亨里克·佩特森

20

简而言之:

这是我建议的代码:

$myarray =  array_values(array_filter(array_map('trim', $myarray), 'strlen'));

说明:

我认为使用array_filter是好的,但还不够,因为值就像space\n,...保留在数组中,通常是不好的。

所以,我建议你使用混合array_filterarray_map

array_map用于修剪,array_filter用于删除空值,strlen用于保留0值,以及array_values在需要时用于重新索引。

样品:

$myarray = array("\r", "\n", "\r\n", "", " ", "0", "a");

// "\r", "\n", "\r\n", " ", "a"
$new1 = array_filter($myarray);

// "a"
$new2 = array_filter(array_map('trim', $myarray));

// "0", "a"
$new3 = array_filter(array_map('trim', $myarray), 'strlen');

// "0", "a" (reindex)
$new4 = array_values(array_filter(array_map('trim', $myarray), 'strlen'));

var_dump($new1, $new2, $new3, $new4);

结果:

array(5) {
  [0]=>
" string(1) "
  [1]=>
  string(1) "
"
  [2]=>
  string(2) "
"
  [4]=>
  string(1) " "
  [6]=>
  string(1) "a"
}
array(1) {
  [6]=>
  string(1) "a"
}
array(2) {
  [5]=>
  string(1) "0"
  [6]=>
  string(1) "a"
}
array(2) {
  [0]=>
  string(1) "0"
  [1]=>
  string(1) "a"
}

在线测试:

http://phpio.net/s/5yg0



12

投票最多的答案是错误的,或者至少不是完全正确的,因为OP仅在谈论空白字符串。这是一个详尽的解释:

是什么意思?

首先,我们必须就意味着什么达成共识。您是说要过滤掉:

  1. 空字符串只(“”)?
  2. 严格假值?($element === false
  3. falsey值?(即0、0.0,“”,“ 0”,NULL,array()...)
  4. 相当于PHP的empty()功能?

您如何筛选出值

过滤出空字符串

$filtered = array_diff($originalArray, array(""));

要仅过滤出严格错误的值,必须使用回调函数:

$filtered = array_diff($originalArray, 'myCallback');
function myCallback($var) {
    return $var === false;
}

该回调函数对于要过滤掉“假”值的任何组合(除了一些值)也很有用。(例如,过滤每个nullfalse,等等,仅保留0):

$filtered = array_filter($originalArray, 'myCallback');
function myCallback($var) {
    return ($var === 0 || $var === '0');
}

第三和第四种情况(最后出于我们的目的)是等效的,为此,您只需要使用默认值:

$filtered = array_filter($originalArray);

2
如果要取出nullfalse,但保留0,则还可以使用php的内置strlen函数作为回调。
Cullub '16

10

我必须这样做以保持(string)0的数组值

$url = array_filter($data, function ($value) {
  return (!empty($value) || $value === 0 || $value==='0');
});

9
$a = array(1, '', '', '', 2, '', 3, 4);
$b = array_values(array_filter($a));

print_r($b)

9

对于多维数组

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


9
function trim_array($Array)
{
    foreach ($Array as $value) {
        if(trim($value) === '') {
            $index = array_search($value, $Array);
            unset($Array[$index]);
        }
    }
    return $Array;
}

7

我使用以下脚本从数组中删除空元素

for ($i=0; $i<$count($Array); $i++)
  {
    if (empty($Array[$i])) unset($Array[$i]);
  }

7

只是想为循环做出贡献...还解决键中的空白...

就我而言,我想在操作完成后保留顺序的数组键(不只是我一直在盯着的奇数。设置代码以查找奇数键对我来说似乎很脆弱,并且对未来不友好。)

我正在寻找更像这样的东西:http : //gotofritz.net/blog/howto/removing-empty-array-elements-php/

array_filter和array_slice的组合可以解决问题。

$example = array_filter($example); $example = array_slice($example,0);

效率或基准方面一无所知,但确实可行。


我认为array_values将具有与array_slice相同的结果。就以后阅读代码并理解其作用而言,这似乎更为直观。
arlomedia

6
$my = ("0"=>" ","1"=>"5","2"=>"6","3"=>" ");   

foreach ($my as $key => $value) {
    if (is_null($value)) unset($my[$key]);
}

foreach ($my as $key => $value) {
    echo   $key . ':' . $value . '<br>';
} 

输出

1:5

2:6



5

只需一行:更新(感谢@suther):

$array_without_empty_values = array_filter($array);

不需要第二个参数:$ clean_array = array_filter($ dirty_array);
suther 2014年


4

删除空数组元素

function removeEmptyElements(&$element)
{
    if (is_array($element)) {
        if ($key = key($element)) {
            $element[$key] = array_filter($element);
        }

        if (count($element) != count($element, COUNT_RECURSIVE)) {
            $element = array_filter(current($element), __FUNCTION__);
        }

        return $element;
    } else {
        return empty($element) ? false : $element;
    }
}

$data = array(
    'horarios' => array(),
    'grupos' => array(
        '1A' => array(
            'Juan' => array(
                'calificaciones' => array(
                    'Matematicas' => 8,
                    'Español' => 5,
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => 20,
                    'febrero' => 10,
                    'marzo' => '',
                )
            ),
            'Damian' => array(
                'calificaciones' => array(
                    'Matematicas' => 10,
                    'Español' => '',
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => 20,
                    'febrero' => '',
                    'marzo' => 5,
                )
            ),
        ),
        '1B' => array(
            'Mariana' => array(
                'calificaciones' => array(
                    'Matematicas' => null,
                    'Español' => 7,
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => null,
                    'febrero' => 5,
                    'marzo' => 5,
                )
            ),
        ),
    )
);

$data = array_filter($data, 'removeEmptyElements');
var_dump($data);

有用!


3

按照您的方法,您可以将这些元素捕获到另一个数组中,然后像下面那样使用它,

foreach($linksArray as $link){
   if(!empty($link)){
      $new_arr[] = $link
   }
}

print_r($new_arr);

1

试试这个****示例

$or = array(
        'PersonalInformation.first_name' => $this->request->data['User']['first_name'],
        'PersonalInformation.last_name' => $this->request->data['User']['last_name'],
        'PersonalInformation.primary_phone' => $this->request->data['User']['primary_phone'],
        'PersonalInformation.dob' => $this->request->data['User']['dob'],
        'User.email' => $this->request->data['User']['email'],
    );



 $or = array_filter($or);

    $condition = array(
        'User.role' => array('U', 'P'),
        'User.user_status' => array('active', 'lead', 'inactive'),
        'OR' => $or
    );

1
这是什么?还有很多其他非常相关的答案。您要在这里添加什么?
费利克斯·加侬-格雷尼尔

在这里检查网址是什么问题!/ *删除空数组元素* /
Ashish pathak

1

我认为array_walk在这里更合适

$linksArray = array('name', '        ', '  342', '0', 0.0, null, '', false);

array_walk($linksArray, function(&$v, $k) use (&$linksArray){
    $v = trim($v);
    if ($v == '')
        unset($linksArray[$k]);
});
print_r($linksArray);

输出:

Array
(
    [0] => name
    [2] => 342
    [3] => 0
    [4] => 0
)
  • 即使用户添加多个空格,我们也确保删除了空值
  • 我们还从有效值中修剪了空白区域

  • 最后,只有(null),(Boolean False)和('')被视为空字符串

至于False删除它是可以的,因为AFAIK用户不能提交布尔值。


0

对于这些类型的事情,最好明确地说明您想要什么和不想要什么。

这将帮助下一个家伙不要因array_filter()没有回调而感到惊讶。例如,我结束了这个问题,因为我忘记了是否array_filter()删除NULL。我浪费了本可以使用下面的解决方案并得到答案的时间。

同样,该逻辑与语言无关,因为可以将代码复制到另一种语言中,而不必了解php函数的行为(如未array_filter传递回调时)。

在我的解决方案中,一目了然。删除条件以保留某些内容或添加新条件以过滤其他值。

array_filter()因为我只是向它传递了一个自定义的回调函数,所以请忽略它的实际用法-如果需要,可以继续将其提取到自己的函数中。我只是将其用作糖进行foreach循环。

<?php

$xs = [0, 1, 2, 3, "0", "", false, null];

$xs = array_filter($xs, function($x) {
    if ($x === null) { return false; }
    if ($x === false) { return false; }
    if ($x === "") { return false; }
    if ($x === "0") { return false; }
    return true;
});

$xs = array_values($xs); // reindex array   

echo "<pre>";
var_export($xs);

这种方法的另一个好处是,您可以将过滤谓词分解为一个抽象函数,该抽象函数对每个数组过滤单个值并构建为可组合的解决方案。

请参阅此示例和内联注释以获取输出。

<?php

/**
 * @param string $valueToFilter
 *
 * @return \Closure A function that expects a 1d array and returns an array
 *                  filtered of values matching $valueToFilter.
 */
function filterValue($valueToFilter)
{
    return function($xs) use ($valueToFilter) {
        return array_filter($xs, function($x) use ($valueToFilter) {
            return $x !== $valueToFilter;
        });
    };
}

// partially applied functions that each expect a 1d array of values
$filterNull = filterValue(null);
$filterFalse = filterValue(false);
$filterZeroString = filterValue("0");
$filterEmptyString = filterValue("");

$xs = [0, 1, 2, 3, null, false, "0", ""];

$xs = $filterNull($xs);        //=> [0, 1, 2, 3, false, "0", ""]
$xs = $filterFalse($xs);       //=> [0, 1, 2, 3, "0", ""]
$xs = $filterZeroString($xs);  //=> [0, 1, 2, 3, ""]
$xs = $filterEmptyString($xs); //=> [0, 1, 2, 3]

echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]

现在,您可以动态创建一个名为filterer()using 的函数pipe(),它将为您应用这些部分应用的函数。

<?php

/**
 * Supply between 1..n functions each with an arity of 1 (that is, accepts
 * one and only one argument). Versions prior to php 5.6 do not have the
 * variadic operator `...` and as such require the use of `func_get_args()` to
 * obtain the comma-delimited list of expressions provided via the argument
 * list on function call.
 *
 * Example - Call the function `pipe()` like:
 *
 *   pipe ($addOne, $multiplyByTwo);
 *
 * @return closure
 */
function pipe()
{
    $functions = func_get_args(); // an array of callable functions [$addOne, $multiplyByTwo]
    return function ($initialAccumulator) use ($functions) { // return a function with an arity of 1
        return array_reduce( // chain the supplied `$arg` value through each function in the list of functions
            $functions, // an array of functions to reduce over the supplied `$arg` value
            function ($accumulator, $currFn) { // the reducer (a reducing function)
                return $currFn($accumulator);
            },
            $initialAccumulator
        );
    };
}

/**
 * @param string $valueToFilter
 *
 * @return \Closure A function that expects a 1d array and returns an array
 *                  filtered of values matching $valueToFilter.
 */
function filterValue($valueToFilter)
{
    return function($xs) use ($valueToFilter) {
        return array_filter($xs, function($x) use ($valueToFilter) {
            return $x !== $valueToFilter;
        });
    };
}

$filterer = pipe(
    filterValue(null),
    filterValue(false),
    filterValue("0"),
    filterValue("")
);

$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterer($xs);

echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.