8

I want to remove all null or blank value but not false and 0 value from recursive array.

function isNotNull($val) {
    if(is_array($val)) {
        $ret = array_filter($val, 'isNotNull');
        return $ret;
    } else {
        return (!is_null($val) && $val !== '');
   }

}

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

Input:

$arr = array(
"stringKey" => "Abc",
"boolKey" => false,
"zeroKey" => 0,
"blankKey" => '',
"newArr" => array(
    "stringKey2"=>"Abc2", 
    "boolKey2"=>false, 
    "zeroKey2" => 0, 
    "blankKey2"=>"", 
    "blankArr" => array()
    )
);

This give output:

Array
(
    [stringKey] => Abc
    [boolKey] => 
    [zeroKey] => 0
    [newArr] => Array
        (
            [stringKey2] => Abc2
            [boolKey2] => 
            [zeroKey2] => 0
            [blankKey2] => 
            [blankArr] => Array
                (
                )
        )
)

But i want to bellow output:

 Array
(
    [stringKey] => Abc
    [boolKey] => 
    [zeroKey] => 0
    [newArr] => Array
        (
            [stringKey2] => Abc2
            [boolKey2] => 
            [zeroKey2] => 0
        )
)

I used array_filter with callback function but it only filter simple array not multidimensional array. I don't want to use loop.

5

3 Answers 3

7

You could combine array_map and array_filter in an recursive called function. Something like this could work for you.

function filterNotNull($array) {
    $array = array_map(function($item) {
        return is_array($item) ? filterNotNull($item) : $item;
    }, $array);
    return array_filter($array, function($item) {
        return $item !== "" && $item !== null && (!is_array($item) || count($item) > 0);
    });
}
Sign up to request clarification or add additional context in comments.

Comments

2

Don't need to reinvent recursion yourself. You can use RecursiveCallbackFilterIterator:

$iterator = new RecursiveIteratorIterator(
    new RecursiveCallbackFilterIterator(
        new RecursiveArrayIterator($arr),
        function ($value) {
            return $value !== null && $value !== '';
        }
    )
);

$result = iterator_to_array($iterator);

Here is working demo.

You should try to use as much stuff from Standard PHP Library (SPL) as you can.

UPDATE: As it is stated in the comments, the solution with iterator not actually suits for this purpose.

In the comments to the array_walk_recursive function you can find the implementation of walk_recursive_remove function:

function walk_recursive_remove (array $array, callable $callback) { 
    foreach ($array as $k => $v) { 
        if (is_array($v)) { 
            $array[$k] = walk_recursive_remove($v, $callback); 
        } else { 
            if ($callback($v, $k)) { 
                unset($array[$k]); 
            } 
        } 
    } 

    return $array; 
} 

This generalized version of recursion function takes criteria in the form of callback. Having this function you can remove empty elements like this:

$result = walk_recursive_remove($arr, function ($value) {
    return $value === null || $value === '';
});

Here is working demo.

3 Comments

@Philipp, yes, my bad. I have updated my answer. Thank you for pointing this.
Nice solution. Is there a way to let it remove sub-arrays with a certain key instead of a value?
@DønerM., thank you. $key is passed as a second parameter to the callback. So you can use it to match criteria.
0

Here you require filtering of an array for empty string. In this code below you can add no of checks to filter it recursively. Hope it will work fine.

Try this code snippet here

<?php

ini_set('display_errors', 1);
//Using more complexed sample array for filter it.
$arr = array(
    "stringKey" => "Abc",
    "boolKey" => false,
    "zeroKey" => 0,
    "blankKey" => '',
    "newArr" => array(
        "stringKey2" => "Abc2",
        "boolKey2" => false,
        "zeroKey2" => 0,
        "blankKey2" => "",
        "blankArr" => array(
            "blankString"=>"",
            "zeroKey"=>0,
            "blankArr3"=>array()
        )
    )
);

$result=recursiveFilter($arr);
print_r($result);


function recursiveFilter($value)
{
    foreach ($value as $key => $value1)
    {
        if ($value1 === "")  unset($value[$key]);//you can add no. of conditions here.
        else if (is_array($value1)) $value[$key] = recursiveFilter($value1);
    }
    return $value;
}

Output:

Array
(
    [stringKey] => Abc
    [boolKey] => 
    [zeroKey] => 0
    [newArr] => Array
        (
            [stringKey2] => Abc2
            [boolKey2] => 
            [zeroKey2] => 0
            [blankArr] => Array
                (
                    [zeroKey] => 0
                    [blankArr3] => Array
                        (
                        )

                )

        )

)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.