使用递归重构PHP数组:提取子数组type值作为父级值
嵌套PHP数组的递归转换实现
原数组
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值作为对应父级键的值,深层嵌套数组同样处理:
array ( 'extension' => 'string', 'filename' => 'string', 'size' => 'number', 'created' => array ( 'date' => 'string', 'timezone' => 'string', 'timezone_type' => 'number' ), 'name' => 'string', 'modified' => array ( 'date' => 'string', 'timezone' => 'string', 'timezone_type' => 'number' ), 'description' => 'string', 'type' => 'string', 'uuid' => 'string', )
现有代码问题
当前代码仅能处理数组第一层,无法递归处理深层嵌套结构,且优先级逻辑(example > format > type)不符合需求:
$fields = array ( // 原数组内容同上 ); 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', )
修正后的代码
重新设计递归逻辑:
- 遍历数组每个元素,判断当前值是否为数组
- 如果是数组且包含
type键,直接将该元素替换为type的值 - 如果是数组但不包含
type键(深层嵌套父数组),递归处理该子数组
$fields = array ( // 原数组内容 ); self::traverseArray($fields); public static function traverseArray(&$array) { foreach ($array as $key => &$value) { if (is_array($value)) { if (isset($value['type'])) { $value = $value['type']; } else { self::traverseArray($value); } } } unset($value); }
运行修正后的代码,结果与期望一致:
array ( 'extension' => 'string', 'filename' => 'string', 'size' => 'number', 'created' => array ( 'date' => 'string', 'timezone' => 'string', 'timezone_type' => 'number' ), 'name' => 'string', 'modified' => array ( 'date' => 'string', 'timezone' => 'string', 'timezone_type' => 'number' ), 'description' => 'string', 'type' => 'string', 'uuid' => 'string', )
内容的提问来源于stack exchange,提问作者bmp99
相关产品推荐
相关产品推荐

