无法过滤多维关联数组:如何提取指定字段生成新数组?
问题:筛选数组后提取指定字段失败,如何生成精简数组?
我通过GET请求访问API,先用以下代码筛选出schedule.type为weekly的元素:
$results = array_filter($body, function($item) { if(!isset($item['schedule']['type'])) return false; return $item['schedule']['type'] == "weekly"; });
返回的数组结构精简版如下:
array ( 6 => array ( 'foo' => 'other fields x 100', 'title' => 'Episode 1 Title', 'automatically_title_stream' => false, 'stream_title' => 'Episode 1 Title', 'stream_description' => 'Join us each afternoon for real-time market analysis and live futures trading in this interactive live stream event.', 'rtmp_link' => 'rtmp://rtmp-global.cloud.vimeo.com/live', 'rtmps_link' => 'rtmps://rtmp-global.cloud.vimeo.com:443/live', 'stream_key' => '97deb5f6-9bef-4e1c-91f8-d39f72657290', 'schedule' => array ( 'type' => 'weekly', 'start_time' => NULL, 'daily_time' => '19:15:00Z', 'scheduled_time' => NULL, 'weekdays' => array ( 0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, ), ), ), 7 => array ( 'foo' => 'other fields x 100', 'title' => 'Episode 2 Title', 'automatically_title_stream' => false, 'stream_title' => 'Bars Closing', 'stream_description' => 'Join us each afternoon for real-time market analysis and live futures trading in this interactive live stream event.', 'rtmp_link' => 'rtmp://rtmp-global.cloud.vimeo.com/live', 'rtmps_link' => 'rtmps://rtmp-global.cloud.vimeo.com:443/live', 'stream_key' => '97deb5f6-9bef-4e1c-91f8-d39f72657290', 'schedule' => array ( 'type' => 'weekly', 'start_time' => NULL, 'daily_time' => '19:15:00Z', 'scheduled_time' => NULL, 'weekdays' => array ( 0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, ), ), ) )
这段筛选代码能正常工作,但返回的数组过于庞大(超过56000行),我只需要保留title、stream_description和weekdays字段。尝试用以下代码处理时得到空数组:
$allowed = ['title', 'stream_description', 'weekdays']; $filtered = array_filter( $results, fn ($key) => in_array($key, $allowed), ARRAY_FILTER_USE_KEY );
请问如何从指定键列表生成新数组,剔除不必要的数据?
问题原因
你用array_filter加ARRAY_FILTER_USE_KEY是在过滤外层数组的键(也就是示例中的6、7这些索引),但实际需求是过滤每个子数组里的字段,逻辑不匹配导致返回空数组。
解决方案
1. 针对当前需求的快速实现
遍历筛选后的$results数组,提取顶层指定字段,并单独处理嵌套的weekdays:
$allowed = ['title', 'stream_description']; $final = []; foreach ($results as $key => $item) { // 提取顶层允许的字段 $entry = array_intersect_key($item, array_flip($allowed)); // 加入嵌套的weekdays字段,兼容字段不存在的情况 $entry['weekdays'] = $item['schedule']['weekdays'] ?? []; $final[$key] = $entry; }
2. 简洁写法(PHP 7.4+)
用array_map结合匿名函数,直观处理固定字段:
$final = array_map(function($item) { return [ 'title' => $item['title'], 'stream_description' => $item['stream_description'], 'weekdays' => $item['schedule']['weekdays'] ?? [] ]; }, $results);
3. 通用深层字段提取函数(适配复杂数组)
如果需要处理多层嵌套、字段不固定的复杂数组,可以封装一个通用函数:
function extractArrayFields(array $sourceData, array $fieldMap) { $result = []; foreach ($sourceData as $key => $item) { $entry = []; foreach ($fieldMap as $alias => $path) { // 支持两种格式:直接写字段名,或用点分隔嵌套路径 $segments = is_string($path) ? explode('.', $path) : $path; $currentValue = $item; foreach ($segments as $segment) { if (!isset($currentValue[$segment])) { $currentValue = null; break; } $currentValue = $currentValue[$segment]; } if ($currentValue !== null) { $entry[is_string($alias) ? $alias : end($segments)] = $currentValue; } } $result[$key] = $entry; } return $result; } // 使用示例:指定需要的字段,嵌套字段用点分隔 $fieldMap = [ 'title', 'stream_description', 'weekdays' => 'schedule.weekdays' ]; $final = extractArrayFields($results, $fieldMap);
内容的提问来源于stack exchange,提问作者Dirty Bird Design
相关产品推荐
相关产品推荐

