使用递归重建PHP数组

klr1opcd  于 2023-01-16  发布在  PHP
关注(0)|答案(1)|浏览(125)

我有以下数组:

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',
  ),
)

我尝试使用递归循环遍历数组,并从子数组中获取'type'的值,使其成为父数组的值。例如,end result:

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

我可以产生一个在第一层数组上有效的结果,但是不能让它遍历到嵌套数组中。

$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'] ;
                }
            }
        }
    }

其输出:

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',
)
sr4lhrrt

sr4lhrrt1#

你的函数中有太多的循环,这让你很困惑。你需要从一个简单的测试开始,确定这个值是另一个字段数组,还是你的type/format/example数组。看起来测试type键是否存在是一种方法。如果是另一个值数组,进行递归调用,if not保存值。你不需要在递归调用分支中有另一个foreach循环,当新的函数调用发生时就会发生。
你还需要在原始数组中保留递归数组的结果。如果你只使用一个返回值,而不是乱加引用,这会更容易管理。

$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;
}

相关问题