简体   繁体   English

删除空数组元素

[英]Remove empty array elements

Some elements in my array are empty strings based on what the user has submitted.根据用户提交的内容,我的数组中的某些元素是空字符串。 I need to remove those elements.我需要删除这些元素。 I have this:我有这个:

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

But it doesn't work.但它不起作用。 $linksArray still has empty elements. $linksArray仍然有空元素。 I have also tried doing it with the empty() function, but the outcome is the same.我也试过用empty()函数来做,但结果是一样的。

As you're dealing with an array of strings, you can simply use array_filter() , which conveniently handles all this for you:当您处理字符串数组时,您可以简单地使用array_filter() ,它可以方便地为您处理所有这些:

print_r(array_filter($linksArray));

Keep in mind that if no callback is supplied , all entries of array equal to FALSE (see converting to boolean ) will be removed.请记住,如果未提供回调,则数组中所有等于FALSE条目(请参阅转换为 boolean )将被删除。 So if you need to preserve elements that are ie exact string '0' , you will need a custom callback:因此,如果您需要保留精确字符串'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 !== "";')));

You can use array_filter to remove empty elements:您可以使用array_filter删除空元素:

$emptyRemoved = array_filter($linksArray);

If you have (int) 0 in your array, you may use the following:如果数组中有(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;
}

EDIT: Maybe your elements are not empty per se but contain one or more spaces... You can use the following before using array_filter编辑:也许您的元素本身不是空的,而是包含一个或多个空格...您可以在使用array_filter之前使用以下array_filter

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

The most popular answer on this topic is absolutely INCORRECT.关于这个话题最流行的答案是绝对不正确的。

Consider the following PHP script:考虑以下 PHP 脚本:

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

Why is this?为什么是这样? Because a string containing a single '0' character also evaluates to boolean false, so even though it's not an empty string, it will still get filtered.因为包含单个 '0' 字符的字符串也计算为布尔 false,所以即使它不是空字符串,它仍然会被过滤。 That would be a bug.那将是一个错误。

Passing the built-in strlen function as the filtering function will work, because it returns a non-zero integer for a non-empty string, and a zero integer for an empty string.将内置 strlen 函数作为过滤函数传递将起作用,因为它为非空字符串返回一个非零整数,为空字符串返回一个零整数。 Non-zero integers always evaluate to true when converted to boolean, while zero integers always evaluate to false when converted to boolean.非零整数在转换为布尔值时总是评估为真,而零整数在转换为布尔值时总是评估为假。

So, the absolute, definitive, correct answer is:所以,绝对的、确定的、正确的答案是:

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

"If no callback is supplied, all entries of input equal to FALSE will be removed." “如果没有提供回调,所有等于 FALSE 的输入条目将被删除。” -- http://php.net/manual/en/function.array-filter.php -- http://php.net/manual/en/function.array-filter.php

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

You can just do你可以做

array_filter($array)

array_filter: "If no callback is supplied, all entries of input equal to FALSE will be removed." array_filter: "如果没有提供回调,所有等于 FALSE 的输入条目将被删除。" This means that elements with values NULL, 0, '0', '', FALSE, array() will be removed too.这意味着值为 NULL、0、'0'、''、FALSE、array() 的元素也将被删除。

The other option is doing另一种选择是做

array_diff($array, array(''))

which will remove elements with values NULL, '' and FALSE.这将删除值为 NULL、'' 和 FALSE 的元素。

Hope this helps :)希望这可以帮助 :)

UPDATE更新

Here is an example.这是一个例子。

$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())

To sum up:总结:

  • 0 or '0' will remove 0 and '0' 0 或 '0' 将删除 0 和 '0'
  • NULL, FALSE or '' will remove NULL, FALSE and '' NULL、FALSE 或 '' 将删除 NULL、FALSE 和 ''
foreach($linksArray as $key => $link) 
{ 
    if($link === '') 
    { 
        unset($linksArray[$key]); 
    } 
} 
print_r($linksArray); 

Another one liner to remove empty ("" empty string) elements from your array.另一个用于从数组中删除空("" 空字符串)元素的衬垫。

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

Note: This code deliberately keeps null , 0 and false elements.注意:这段代码故意保留null0false元素。


Or maybe you want to trim your array elements first:或者,您可能想先修剪数组元素:

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

Note: This code also removes null and false elements.注意:此代码还删除了nullfalse元素。

In short:简而言之:

This is my suggested code:这是我建议的代码:

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

Explanation:解释:

I thinks use array_filter is good, but not enough, because values be like space and \\n ,... keep in the array and this is usually bad.我认为使用array_filter是好的,但还不够,因为值就像space\\n ,...保留在数组中,这通常是不好的。

So I suggest you use mixture ‍‍ array_filter and array_map .所以,我建议你使用混合array_filterarray_map

array_map is for trimming, array_filter is for remove empty values, strlen is for keep 0 value, and array_values is for re indexing if you needed. array_map用于修剪, array_filter用于删除空值, strlen用于保留0值, array_values用于根据需要重新索引。

Samples:样品:

$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);

Results:结果:

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

Online Test:在线测试:

http://sandbox.onlinephpfunctions.com/code/e02f5d8795938be9f0fa6f4c17245a9bf8777404 http://sandbox.onlinephpfunctions.com/code/e02f5d8795938be9f0fa6f4c17245a9bf8777404

If you are working with a numerical array and need to re-index the array after removing empty elements, use the array_values function:如果您使用的是数值数组并且需要在删除空元素后重新索引数组,请使用array_values函数:

array_values(array_filter($array));

Also see: PHP reindex array?另请参阅: PHP 重新索引数组?

The most voted answer is wrong or at least not completely true as the OP is talking about blank strings only.投票最多的答案是错误的,或者至少不完全正确,因为 OP 只讨论空白字符串。 Here's a thorough explanation:这是一个彻底的解释:

What does empty mean?是什么意思?

First of all, we must agree on what empty means.首先,我们必须就空的含义达成一致。 Do you mean to filter out:你的意思是过滤掉:

  1. the empty strings only ("")?只有空字符串(“”)?
  2. the strictly false values?严格的错误值? ( $element === false ) ( $element === false )
  3. the falsey values?值? (ie 0, 0.0, "", "0", NULL, array()...) (即 0, 0.0, "", "0", NULL, array()...)
  4. the equivalent of PHP's empty() function?相当于 PHP 的empty()函数?

How do you filter out the values你如何过滤掉这些值

To filter out empty strings only :过滤空字符串

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

To only filter out strictly false values, you must use a callback function:要仅过滤掉严格的错误值,您必须使用回调函数:

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

The callback is also useful for any combination in which you want to filter out the "falsey" values, except some.回调对于您想要过滤掉“falsey”值的任何组合也很有用,除了一些。 (For example, filter every null and false , etc, leaving only 0 ): (例如,过滤每一个nullfalse等,只留下0 ):

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

Third and fourth case are (for our purposes at last) equivalent, and for that all you have to use is the default:第三种和第四种情况(最终出于我们的目的)是等价的,为此您必须使用默认值:

$filtered = array_filter($originalArray);

I had to do this in order to keep an array value of (string) 0我必须这样做才能保持 (string) 0 的数组值

$url = array_filter($data, function ($value) {
  return (!empty($value) || $value === 0 || $value==='0');
});
$a = array(1, '', '', '', 2, '', 3, 4);
$b = array_values(array_filter($a));

print_r($b)

For multidimensional array对于多维数组

$data = array_map('array_filter', $data);
$data = array_filter($data);
function trim_array($Array)
{
    foreach ($Array as $value) {
        if(trim($value) === '') {
            $index = array_search($value, $Array);
            unset($Array[$index]);
        }
    }
    return $Array;
}
$out_array = array_filter($input_array, function($item) 
{ 
    return !empty($item['key_of_array_to_check_whether_it_is_empty']); 
}
);

I use the following script to remove empty elements from an array我使用以下脚本从数组中删除空元素

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

Just want to contribute an alternative to loops...also addressing gaps in keys...只是想为循环贡献一个替代方案......还解决密钥中的差距......

In my case I wanted to keep sequential array keys when the operation was complete (not just odd numbers, which is what I was staring at. Setting up code to look just for odd keys seemed fragile to me and not future-friendly.)在我的情况下,我想在操作完成时保留顺序数组键(不仅仅是奇数,这正是我所关注的。设置代码以查找奇数键对我来说似乎很脆弱,对未来不友好。)

I was looking for something more like this: http://gotofritz.net/blog/howto/removing-empty-array-elements-php/我正在寻找更像这样的东西: http : //gotofritz.net/blog/howto/removing-empty-array-elements-php/

The combination of array_filter and array_slice does the trick. array_filter 和 array_slice 的组合可以解决问题。

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

No idea on efficiencies or benchmarks but it works.不知道效率或基准,但它有效。

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

$array_without_empty_values = array_filter($array);
$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>';
} 

output输出

1:5 1:5

2:6 2:6

foreach($arr as $key => $val){
   if (empty($val)) unset($arr[$key];
}

use array_filter function to remove empty values:使用array_filter函数删除空值:

$linksArray = array_filter($linksArray);
print_r($linksArray);

Remove empty array elements删除空数组元素

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

¡it works!有用!

I think array_walk is much more suitable here我认为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);

Output:输出:

Array
(
    [0] => name
    [2] => 342
    [3] => 0
    [4] => 0
)
  • We made sure that empty values are removed even if the user adds more than one space即使用户添加了多个空格,我们也确保删除空值

  • We also trimmed empty spaces from the valid values我们还从有效值中修剪了空格

  • Finally, only (null), (Boolean False) and ('') will be considered empty strings最后,只有 (null)、(Boolean False) 和 ('') 会被视为空字符串

As for False it's ok to remove it, because AFAIK the user can't submit boolean values.至于False可以删除它,因为 AFAIK 用户不能提交布尔值。

As per your method, you can just catch those elements in an another array and use that one like follows,根据您的方法,您可以在另一个数组中捕获这些元素并使用如下所示的元素,

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

print_r($new_arr);

try this ** **Example试试这个 ** ** 例子

$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
    );

With these types of things, it's much better to be explicit about what you want and do not want.对于这些类型的事情,最好明确说明您想要什么和不想要什么。

It will help the next guy to not get caught by surprise at the behaviour of array_filter() without a callback.这将有助于下一个人在没有回调的情况下不会对array_filter()的行为感到惊讶。 For example, I ended up on this question because I forgot if array_filter() removes NULL or not.例如,我最终回答了这个问题,因为我忘记了array_filter()删除了NULL I wasted time when I could have just used the solution below and had my answer.当我可以使用下面的解决方案并得到我的答案时,我浪费了时间。

Also, the logic is language angnostic in the sense that the code can be copied into another language without having to under stand the behaviour of a php function like array_filter when no callback is passed.此外,逻辑是语言不可知的,因为代码可以被复制到另一种语言中,而无需array_filter没有回调传递时像array_filter这样的 php 函数的行为。

In my solution, it is clear at glance as to what is happening.在我的解决方案中,正在发生的事情一目了然。 Remove a conditional to keep something or add a new condition to filter additional values.删除条件以保留某些内容或添加新条件以过滤其他值。

Disregard the actual use of array_filter() since I am just passing it a custom callback - you could go ahead and extract that out to its own function if you wanted.忽略array_filter()的实际使用,因为我只是向它传递一个自定义回调 - 如果需要,您可以继续将其提取到它自己的函数中。 I am just using it as sugar for a foreach loop.我只是将它用作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);

Another benefit of this approach is that you can break apart the filtering predicates into an abstract function that filters a single value per array and build up to a composable solution.这种方法的另一个好处是您可以将过滤谓词分解为一个抽象函数,该函数过滤每个数组的单个值并构建一个可组合的解决方案。

See this example and the inline comments for the output.请参阅此示例和输出的内联注释。

<?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]

Now you can dynamically create a function called filterer() using pipe() that will apply these partially applied functions for you.现在,您可以使用pipe()动态创建一个名为filterer()的函数,该函数将为您应用这些部分应用的函数。

<?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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM