Home > OS >  Rebuilding PHP array using recursion
Rebuilding PHP array using recursion

Time:01-15

I have the following array:

array (
  'extension' => 
  array (
    'type' => 'string',
    'format' => 'file-extension',
  ),
  'filename' => 
  array (
    'type' => 'string',
    'format' => 'filename',
  ),
  'size' => 
  array (
    'type' => 'number',
  ),
  'created' => 
  array (
    'date' => 
    array (
      'type' => 'string',
      'format' => 'date-time',
    ),
    'timezone' => 
    array (
      'type' => 'string',
      'format' => 'string',
      'example' => 'America/New_York',
    ),
    'timezone_type' => 
    array (
      'type' => 'number',
    ),
  ),
  'name' => 
  array (
    'type' => 'string',
    'format' => 'string',
  ),
  'modified' => 
  array (
    'date' => 
    array (
      'type' => 'string',
      'format' => 'date-time',
    ),
    'timezone' => 
    array (
      'type' => 'string',
      'format' => 'string',
    ),
    'timezone_type' => 
    array (
      'type' => 'number',
    ),
  ),
  'description' => 
  array (
    'type' => 'string',
    'format' => 'string',
  ),
  'type' => 
  array (
    'type' => 'string',
    'format' => 'string',
  ),
  'uuid' => 
  array (
    'type' => 'string',
    'format' => 'uuid',
  ),
)

I am trying to use recursively loop through the array and take the value of 'type' from the sub array and make it the value of the parent. For example, end result:

array (
  'extension' => 'string',
  'filename' => 'string',
  'size' => 'number',
  'created' => 
  array (
    'date' => 'string'
    'timezone' => 'string',
    'timezone_type' => 'number'
  ),

I am able to produce a result that works on the first level of arrays, but cant get it to traverse into the nested arrays. My code is:

$fields = array (
  'extension' => 
  array (
    'type' => 'string',
    'format' => 'file-extension',
  ),
  'filename' => 
  array (
    'type' => 'string',
    'format' => 'filename',
  ),
  'size' => 
  array (
    'type' => 'number',
  ),
  'created' => 
  array (
    'date' => 
    array (
      'type' => 'string',
      'format' => 'date-time',
    ),
    'timezone' => 
    array (
      'type' => 'string',
      'format' => 'string',
      'example' => 'America/New_York',
    ),
    'timezone_type' => 
    array (
      'type' => 'number',
    ),
  ),
  'name' => 
  array (
    'type' => 'string',
    'format' => 'string',
  ),
  'modified' => 
  array (
    'date' => 
    array (
      'type' => 'string',
      'format' => 'date-time',
    ),
    'timezone' => 
    array (
      'type' => 'string',
      'format' => 'string',
    ),
    'timezone_type' => 
    array (
      'type' => 'number',
    ),
  ),
  'description' => 
  array (
    'type' => 'string',
    'format' => 'string',
  ),
  'type' => 
  array (
    'type' => 'string',
    'format' => 'string',
  ),
  'uuid' => 
  array (
    'type' => 'string',
    'format' => 'uuid',
  ),
);

self::traverseArray($fields);



    public static function traverseArray(&$fields) {

        foreach ($fields as $field => $val) {
            foreach ($val as $value) {
                if (is_array($value)) {
                    foreach ($value as $_key => $_val) {
                        self::traverseArray($val);
                    }
                } else {
                    $fields[$field] = $val['example'] ?? $val['format'] ?? $val['type'] ;
                }
            }
        }
    }

Which outputs:

array (
  'extension' => 'file-extension',
  'filename' => 'filename',
  'size' => 'number',
  'created' => 
  array (
    'date' => 
    array (
      'type' => 'string',
      'format' => 'date-time',
    ),
    'timezone' => 
    array (
      'type' => 'string',
      'format' => 'string',
      'example' => 'America/New_York',
    ),
    'timezone_type' => 
    array (
      'type' => 'number',
    ),
  ),
  'name' => 'string',
  'modified' => 
  array (
    'date' => 
    array (
      'type' => 'string',
      'format' => 'date-time',
    ),
    'timezone' => 
    array (
      'type' => 'string',
      'format' => 'string',
    ),
    'timezone_type' => 
    array (
      'type' => 'number',
    ),
  ),
  'description' => 'string',
  'type' => 'string',
  'uuid' => 'uuid',
)

CodePudding user response:

You have too much looping going on in your function and are making things confusing. You need to start with a simple test to determine if the value is another array of fields, or your type/format/example array. It seems like testing if the type key exists would be the way to do this. If it is another array of values, do your recursive call, if not save the value. You do not need to have another foreach loop in your recursive call branch, that happens when the new function call takes place.

You also need to preserve the result of the recursive array in the original. It's easier to manage this if you just use a return value rather than mess with references.

$fields = convertArray($fields);
print_r($fields);

function convertArray($fields) {
    foreach ($fields as $field => $val) {
        if (array_key_exists('type', $val)) {
            $fields[$field] = $val['example'] ?? $val['format'] ?? $val['type'] ;
        } else {
            $fields[$field] = convertArray($val);
        }
    }
    return $fields;
}
  • Related