讲师中心 微信公众号
AI工具推荐 视频效率加速

PHP数组:在循环中按键聚合相同值的数据结构优化

风墨吖_2174

风墨吖_2174

发布时间:2025-11-02 10:29:00

|

318人浏览过

|

来源于php中文网

原创

PHP数组:在循环中按键聚合相同值的数据结构优化

本教程旨在解决在php中循环处理数据时,如何将具有相同标识符(如日期)的记录高效地聚合到单个父条目下,并将其相关联的子数据(如时间段)作为嵌套数组进行存储。文章将详细阐述一种利用数组键进行条件性分组的优化方法,从而避免生成重复的父条目,最终实现清晰、结构化的数据输出。

在数据处理和展示的场景中,我们经常会遇到需要将扁平化的数据集重构为更具层次感的结构。一个典型的例子是,从数据库中获取了一系列设置,其中包含每天的多个时间段。如果直接遍历这些设置并简单地将它们添加到结果数组中,可能会导致同一天的数据被分散到多个独立的条目中,这不符合我们通常期望的按天分组的逻辑。

初始数据结构与挑战

假设我们有一个 $settings 变量,它包含了从数据库查询到的配置列表。每个配置项都包含 day(日期)、start(开始时间)和 end(结束时间)。

一个常见的初步处理方式可能如下所示:

$items = [];
foreach($settings as $setting){
   $items[] = [
     'day' => $setting->day,
     'periods' => [
       'start' => $setting->start,
       'end' => $setting->end
      ]
   ];
}

这种方法会产生以下类似的结果:

立即学习“PHP免费学习笔记(深入)”;

$items = [
  [
    'day' => 1,
    'periods' => [
      'start' => '08:00',
      'end' => '17:00'
    ]
  ],
  [
    'day' => 2,
    'periods' => [
      'start' => '08:00',
      'end' => '12:00'
    ]
  ],
  [
    'day' => 2,
    'periods' => [
      'start' => '14:00',
      'end' => '17:00'
    ]
  ]
];

可以看到,尽管第二天(day 为 2)有两个不同的时间段,但它们被存储为两个独立的数组元素,每个元素都重复了 day 字段。这与我们期望的按天聚合,并将所有时间段归集到该天下的结构不符。

创意前端视觉设计
创意前端视觉设计

在创建或重塑需要独特视觉方向、应避免通用 AI 生成审美的网站、落地页、仪表盘、UI 组件、海报或应用时使用。

下载

期望的聚合数据结构

我们希望实现的数据结构是,每个日期只出现一次,其下包含一个 periods 数组,该数组中存储了该日期的所有时间段。例如:

$items = [
  [
    'day' => 1,
    'periods' => [
      [
        'start' => '08:00',
        'end' => '17:00'
      ]
    ]
  ],
  [
    'day' => 2,
    'periods' => [
      [
        'start' => '08:00',
        'end' => '12:00'
      ],
      [
        'start' => '14:00',
        'end' => '17:00'
      ]
    ]
  ]
];

解决方案:利用数组键进行条件性分组

要实现上述期望的结构,核心思想是利用待分组的标识符(在这里是 day)作为结果数组的键。这样,我们可以在每次迭代时检查该键是否存在。如果不存在,则创建一个新的父条目;如果已存在,则直接将当前时间段添加到现有父条目的 periods 数组中。

以下是实现这一逻辑的PHP代码:

$items = [];
foreach($settings as $setting){
    // 检查当前日期($setting->day)是否已作为键存在于 $items 数组中
    if (empty($items[$setting->day])) {
        // 如果不存在,则为该日期创建一个新的父条目
        // 'day' 字段用于最终输出,'periods' 初始化为空数组
        $items[$setting->day] = [
            'day' => $setting->day,
            'periods' => [],
        ];
    }

    // 将当前设置的时间段添加到对应日期的 'periods' 数组中
    $items[$setting->day]['periods'][] = [
        'start' => $setting->start,
        'end' => $setting->end
    ];
}

// 如果需要最终结果是一个索引数组(而不是关联数组),可以重新索引
// $items = array_values($items);

代码解析:

  1. $items = [];: 初始化一个空数组,用于存储最终聚合后的数据。
  2. foreach($settings as $setting){ ... }: 遍历从数据库获取的 $settings 数组中的每个设置项。
  3. if (empty($items[$setting->day])) { ... }: 这是实现分组的关键。它检查 $items 数组中是否存在以当前设置项的 day 值为键的元素。
    • empty() 函数在这里用于判断该键是否存在且其值不为“空”(例如 null, false, 0, 空字符串或空数组)。对于我们这种场景,它能有效判断是否是第一次遇到这个 day。
  4. $items[$setting->day] = [ 'day' => $setting->day, 'periods' => [], ];: 如果 empty() 判断为真(即该 day 首次出现),则在 $items 数组中以 day 值为键创建一个新的元素。这个新元素本身是一个关联数组,包含 day 字段和初始化为空数组的 periods 字段。
  5. $items[$setting->day]['periods'][] = [ 'start' => $setting->start, 'end' => $setting->end ];: 无论当前 day 是第一次出现还是已经存在,都会执行这一步。它将当前设置项的 start 和 end 时间作为一个新的关联数组,添加到对应日期的 periods 数组中。[] 语法确保了每次添加都是一个新的元素。

注意事项与总结

  • 键的唯一性与稳定性: 这种方法依赖于作为键的字段(例如 day)在其分组范围内是唯一的。如果 day 字段本身可能重复且不应该作为唯一标识符,则需要选择其他字段或组合字段作为键。
  • 最终数组的类型: 上述解决方案会生成一个关联数组,其键是 day 值。如果最终需要一个从 0 开始的索引数组(例如,为了在前端方便地遍历),可以在循环结束后使用 array_values($items) 函数将关联数组转换为索引数组。
  • 性能: 这种基于键的查找和插入操作在大多数情况下效率很高,尤其适用于处理中等规模的数据集。它避免了在每次迭代中对整个数组进行搜索,从而优化了性能。
  • 可读性与维护性: 这种分组逻辑清晰,易于理解和维护,是处理此类数据聚合问题的标准模式。

通过采用这种利用数组键进行条件性分组的策略,我们可以有效地将扁平化的数据流转换为结构化、层次化的数据集合,从而大大提高数据的可用性和代码的可读性。

热门AI工具

更多
蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

798

2025.12.04

mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

16280

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1183

2024.02.23

java标识符合集
java标识符合集

本专题整合了java标识符相关内容,想了解更多详细内容,请阅读下面的文章。

8910

2025.06.11

c++标识符介绍
c++标识符介绍

本专题整合了c++标识符相关内容,阅读专题下面的文章了解更多详细内容。

3542

2025.08.07

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1838

2023.08.03

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

100

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

Apache Subversion 官方手册
Apache Subversion 官方手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn