skip to Main Content

I am trying to flatten and concatenate some nested arrays in PHP, whatever the dimension of the array, and return a single level array of all the concatenated data.

Given array:

[
   'dashboards' => [
      'statistics' => [
         'tab_names' => [
            'spare',
            'robot',
          ]
       ]
    ]
];

Desired output:

[
   'dashboards_statistics_tab_names_spare',
   'dashboards_statistics_tab_names_robot',
];

However, I tried to adapt some code found here, came up with that:

function flattenArray($array, $prefix = '') {
    $result = [];
    foreach ($array as $key => $value) {
        $newKey = $prefix . $key;
        if (is_array($value)) {
            $result = array_merge($result, flattenArray($value, $newKey . '_'));
        } elseif (is_string($value)) {
            $result[] = $newKey . '_' . $value;
        }
    }
    return $result;
}

The output is almost OK, but I’m having some unwated characters in the strings:

[
   'dashboards_statistics_tab_names_0_spare',
   'dashboards_statistics_tab_names_1_robot',
];

How can I get rid of the numeric keys ?

3

Answers


  1. I just made some changes in your code, if the $key may be a numeric when no index is given.

    I also use rtrim to avoid extra _ at the end of the string when it’s the last value of an array.

    function flattenArray($array, $prefix = '')
    {
        $result = [];
        foreach ($array as $key => $value) {
            if (!is_numeric($key)) {
                $newKey = $prefix . $key;
            } else {
                $newKey = $prefix;
            }
    
            if (is_array($value)) {
                $result = array_merge($result, flattenArray($value, $newKey . '_'));
            } elseif (is_string($value)) {
                $result[] = rtrim($newKey, '_') . '_' . $value;
            }
        }
        return $result;
    }
    
    Login or Signup to reply.
  2. Improving the suggestion of @user3783243 a solution can be this:

    function flattenArray($array, $prefix = '') {
        
        $result = [];
        
        foreach ($array as $key => $value) {
            
             // $newKey = $prefix . $key;
             
            $newKey = $prefix . (!is_numeric($key) ? $key : '') ;
            
            if (is_array($value)) {
                $result = array_merge($result, flattenArray($value, $newKey . '_'));
                
            } elseif (is_string($value)) {
                
                $result[] = $newKey . $value;
            }
        }
        return $result;
    }
    

    The prefix is not updated if the key is numeric (last array level) and also the underscore is not added for values of type string

    Login or Signup to reply.
  3. I think to get rid of the numeric keys, the code for checking for numeric keys should be added to the codebase.

    I attached my code snippet:

    function getFlattenArray($array, $prefix = '') {
        $arr = [];
    
        foreach ($array as $key => $value) {
            $newKey = $prefix . $key;
            if (is_array($value)) {
                $arr = array_merge($arr, flattenArray($value, $newKey . '_'));
            } elseif (is_string($value)) {
                if (!is_numeric($key)) {
                    $arr[] = $newKey . '_' . $value;
                }
            }
        }
        return $arr;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search