skip to Main Content

I’ve the following array:

$variables = [
    "id" => "discountCodeID",
    "test" => null,
    "codeDiscount" => [
        "code" => "discountCode",
        "title" => null,
        "startsAt" => "discountStartsAt",
        "endsAt" => "",
        "usageLimit" => "discountUsageLimit",
        "usesPerOrderLimit" => "discountUsesPerOrderLimit",
        "customerBuys" => [
            "value" => [],
            "items" => "discountCustomerBuysItems"
        ],
        "customerGets" => [
            "value" => "discountCustomerGetsValue",
            "items" => "discountCustomerGetsItems"
        ],
        "customerSelection" => "",
        "appliesOncePerCustomer" => "discountAppliesOncePerCustomer"
    ]
];

Now I wanna remove all the key value pairs where the value is null or "" or [].
But the problem is using simple array filter doesn’t work because of the nested arrays. So I took the following approach:

foreach ($variables as $key => $value) {
    if (is_null($value) || $value === '' || (is_array($value) && empty($value))) {
        unset($variables[$key]);
    } elseif (is_array($value)) {
        $variables[$key] = removeEmptyValuesFromArray($value);
    }
}

function removeEmptyValuesFromArray($array) {
    foreach ($array as $key => $value) {
        if (is_null($value) || $value === '' || (is_array($value) && empty($value))) {
            unset($array[$key]);
        } elseif (is_array($value)) {
            $array[$key] = removeEmptyValuesFromArray($value);
        }
    }
    return $array;
}

print_r($variables);

Well this code works but the problem is the array might become lot larger with more levels of nested arrays. And certainly this wouldn’t be a good solution in that case.

So what approach would you take in this situation?

Arigato Gozaimasu!

3

Answers


  1. You already have a recursion in your function.

    So you don’t need the first foreach loop outside of it. You can simplify your code as follows:

    function removeEmptyValuesFromArray($array) {
        foreach ($array as $key => $value) {
            if (empty($value)) {
                unset($array[$key]);
            } elseif (is_array($value)) {
                $array[$key] = removeEmptyValuesFromArray($value);
            }
        }
        return $array;
    }
    
    $variables = removeEmptyValuesFromArray($variables);
    

    Also, note that you can replace is_null($value) || $value === '' || (is_array($value) && empty($value)) by empty($value)

    Login or Signup to reply.
  2. In order to cater for the edge case where all the elements of a sub-array are removed (and so the sub-array itself should also be removed), I would suggest a slight reordering of the tests in your recursive function:

    function removeEmptyValuesFromArray($array) {
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                $value = removeEmptyValuesFromArray($value);
                $array[$key] = $value;
            }
            if (is_null($value) || $value === '' || (is_array($value) && empty($value))) {
                unset($array[$key]);
            }
        }
        return $array;
    }
    
    Login or Signup to reply.
  3. function array_filter_recursive(array $array): array
    {
      return array_map(
        static fn($value) => is_array($value) ? array_filter_recursive($value) : $value,
        array_filter($array)
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search