PHP按列值分组数组:存储嵌套数据、首尾记录及统计信息
实现指定数组分组与结构化的方案
问题分析
你之前的代码存在几处关键错误:
- 直接对
$dataArray调用explode(' ', $dataArray)是错误的,应该遍历数组内的每个字符串单独拆分 - 后续的数组赋值逻辑存在语法错误,无法正确提取和存储字段
正确实现步骤
1. 初始化目标数组
创建空数组用于存储最终的结构化数据:
$desiredArray = [];
2. 遍历并处理原始数据
循环遍历每条数据,拆分后提取关键字段,逐步构建目标结构:
foreach ($dataArray as $item) { // 拆分当前行的空格分隔数据 $parts = explode(' ', $item); // 提取核心字段:站点标识、访问时间、用户ID $spot = $parts[0]; $time = $parts[4]; $userId = $parts[5]; // 初始化站点对应的结构(首次处理该站点时执行) if (!isset($desiredArray[$spot])) { $desiredArray[$spot] = [ 'user' => [], 'first' => $time, 'last' => $time, 'totalUser' => 0, 'totalAccess' => 0 ]; } // 处理用户访问记录 if (!isset($desiredArray[$spot]['user'][$userId])) { // 首次出现该用户,初始化时间列表并递增用户数 $desiredArray[$spot]['user'][$userId] = []; $desiredArray[$spot]['totalUser']++; } // 添加当前访问时间到用户列表 $desiredArray[$spot]['user'][$userId][] = $time; // 递增总访问次数 $desiredArray[$spot]['totalAccess']++; // 更新最早访问时间 if (strtotime($time) < strtotime($desiredArray[$spot]['first'])) { $desiredArray[$spot]['first'] = $time; } // 更新最晚访问时间 if (strtotime($time) > strtotime($desiredArray[$spot]['last'])) { $desiredArray[$spot]['last'] = $time; } }
3. 关键细节说明
- 使用
strtotime()转换时间字符串为时间戳,确保最早/最晚时间的比较准确 - 站点结构初始化时,先将
first和last设为当前时间,后续再动态更新 totalUser仅在新增用户ID时递增,避免重复统计同一用户
完整可运行代码
$dataArray = [ 0 => "AAAAA 2023 01 25 01:04:00 ID:20fjrjeZZ", 1 => "AAAAA 2023 01 25 01:18:08 ID:13454B43A", 2 => "AAAAA 2023 01 25 02:00:02 ID:18f5hjeWe", 3 => "AAAAA 2023 01 25 04:10:13 ID:13454B43A", 4 => "BBBBB 2023 01 25 01:44:10 ID:Xj74320fj", 5 => "BBBBB 2023 01 25 07:08:58 ID:13454B43A", 6 => "BBBBB 2023 01 25 08:40:52 ID:Ftzkk800Y", 7 => "BBBBB 2023 01 25 14:10:13 ID:18f5hjeWe" ]; $desiredArray = []; foreach ($dataArray as $item) { $parts = explode(' ', $item); $spot = $parts[0]; $time = $parts[4]; $userId = $parts[5]; if (!isset($desiredArray[$spot])) { $desiredArray[$spot] = [ 'user' => [], 'first' => $time, 'last' => $time, 'totalUser' => 0, 'totalAccess' => 0 ]; } if (!isset($desiredArray[$spot]['user'][$userId])) { $desiredArray[$spot]['user'][$userId] = []; $desiredArray[$spot]['totalUser']++; } $desiredArray[$spot]['user'][$userId][] = $time; $desiredArray[$spot]['totalAccess']++; if (strtotime($time) < strtotime($desiredArray[$spot]['first'])) { $desiredArray[$spot]['first'] = $time; } if (strtotime($time) > strtotime($desiredArray[$spot]['last'])) { $desiredArray[$spot]['last'] = $time; } } // 输出结果验证 print_r($desiredArray);
内容的提问来源于stack exchange,提问作者Cem Firat
相关产品推荐
相关产品推荐

