Search code examples
phparraysnullarray-filterarray-unique

How to remove `null` result when using array_unique?


I have the following multidimensional array:

$subregion = [
    [
        "subregion_id"   => "8",
        "subregion_name" => "NORTH_AMERICA",
        "subregion_abbr" => "US"
    ],
    [
        "subregion_id"   => "9",
        "subregion_name" => "NORTH_AMERICA",
        "subregion_abbr" => "CA"
    ],
    [
        "subregion_id"   => "6",
        "subregion_name" => "WE",
        "subregion_abbr" => "South"
    ],
    [
        "subregion_id"   => "0",
        "subregion_name" => null,
        "subregion_abbr" => null
    ],
    [
        "subregion_id"   => "5",
        "subregion_name" => "WE",
        "subregion_abbr" => "North"
    ],
    [
        "subregion_id"   => "0",
        "subregion_name" => null,
        "subregion_abbr" => null
    ]
];

I want to unique that array by its values so I have test the following (from this post):

$subregion = array_map("unserialize", array_unique(array_map("serialize", $subregion)));
$subregion = array_intersect_key($subregion, array_unique(array_map('serialize', $subregion)));
$subregion_unique = array_unique($subregion, SORT_REGULAR);

All of them work (tried one by one) and produces the same output:

$subregion = [
    [
        "subregion_id"   => "8",
        "subregion_name" => "NORTH_AMERICA",
        "subregion_abbr" => "US"
    ],
    [
        "subregion_id"   => "9",
        "subregion_name" => "NORTH_AMERICA",
        "subregion_abbr" => "CA"
    ],
    [
        "subregion_id"   => "6",
        "subregion_name" => "WE",
        "subregion_abbr" => "South"
    ],
    [
        "subregion_id"   => "5",
        "subregion_name" => "WE",
        "subregion_abbr" => "North"
    ],
    [
        "subregion_id"   => "0",
        "subregion_name" => null,
        "subregion_abbr" => null
    ]
];

I want to get rid of the null values on the array because them should not be there. So I have tried this other workaround (found here):

private function is_not_null($var)
{
    return !is_null($var);
}

$unique = array_filter($subregion_unique, 'is_not_null');

But surprise the output of $unique is exactly the same as before, why? What I am missing here?

NOTE I forgot to mention that should be compatible with PHP 5.3.10+

Update: test1

Following @abracadaver instructions this is what I've tried:

$unique = array_map('unserialize', array_unique(array_map('serialize', $subregion)));
$unique = array_map(function($v) { return array_filter($v, 'is_not_null'); }, $unique);

I have changed the function is_not_null($var) above to return result in this way:

return null !== $var;

The result is an array with null values.

PS: Maybe the title is not accurate and the post is tempted to be closed or marked as duplicate, if so please suggest me a better title or change by yourself if you can.


Solution

  • Not sure why you have all that code. This one line gets a unique array:

    $unique = array_map("unserialize", array_unique(array_map("serialize", $subregion)));
    

    Then to filter out the null with your current function:

    $unique = array_map(function($v) { return array_filter($v, 'is_not_null'); }, $unique);
    

    If you don't care if the 0 is removed then it's even shorter and you don't need your function:

    $unique = array_map(function($v) { return array_filter($v); }, $unique);
    

    Then you know you'll have an empty child array, so you can filter it:

    $unique = array_filter($unique);
    

    The SORT_REGULAR makes no difference here, but for when it may, or if you need a different flag, you would just add it in the above array_unique():

    $unique = array_map("unserialize",
                        array_unique(array_map("serialize", $subregion), SORT_REGULAR));