
本文介绍一种基于分类(tx)反向聚合值(rx)的 php 数组分组策略,通过构建“rx 集合 → tx 列表”的映射关系,结合排序与字符串化键实现最优分组,兼顾 null 处理与最大公共集优先原则。
本文介绍一种基于分类(tx)反向聚合值(rx)的 php 数组分组策略,通过构建“rx 集合 → tx 列表”的映射关系,结合排序与字符串化键实现最优分组,兼顾 null 处理与最大公共集优先原则。
在实际业务中(如权限矩阵、标签路由或配置归并),我们常需将一组“实体→分类”映射关系重组织为“分类交集→实体集合”的逆向结构。本例的核心挑战在于:不以原始 value(如 'R1')为分组主键,而是以 categories 中各元素(如 'T1')为枢纽,统计哪些 value 共享同一分类,再将共享相同 value 组合的分类合并为新组——且要求组合尽可能长(即优先生成 [R1,R2,R3,R4] 而非更短的子集),同时正确隔离 NULL 值。
✅ 核心思路:分类驱动 + 字符串化键聚合
- 分离 NULL 特例:所有 value === null 或 category === null 的条目单独归入 $nulls,避免干扰后续逻辑;
- 建立 T → [R] 映射:遍历输入,对每个非空 category(如 'T1'),将其对应的 value(如 'R1')追加至 $categories['T1'];
- 按 R 集合聚类:对每个 T 对应的 R 数组排序后拼接为唯一字符串键(如 ['R1','R2','R3','R4'] → 'R1R2R3R4'),确保相同组合始终生成同一键;
- 合并同键分类:利用该字符串键累积所有归属此 R 组合的 T,最终还原为 ['values' => [...], 'categories' => [...]] 结构。
? 完整可运行代码示例
<?php $input = [
['value' => null, 'categories' => ['T1', 'T2', 'T5']],
['value' => 'R1', 'categories' => [null, 'T1', 'T2', 'T3', 'T4', 'T5', 'T6']],
['value' => 'R2', 'categories' => ['T1', 'T2', 'T3']],
['value' => 'R3', 'categories' => ['T1', 'T2', 'T3']],
['value' => 'R4', 'categories' => ['T1', 'T2']],
];
$nulls = [];
$categories = [];
$tmp = [];
// Step 1: 分离 NULL 并构建 T → [R] 映射
foreach ($input as $inp) {
if ($inp['value'] === null) {
$nulls[] = ['values' => [null], 'categories' => $inp['categories']];
continue;
}
$Rx = $inp['value'];
foreach ($inp['categories'] as $Tx) {
if ($Tx === null) {
$nulls[] = ['values' => [$Rx], 'categories' => [null]];
continue;
}
$categories[$Tx][] = $Rx;
}
}
// Step 2: 按 R 集合聚类(排序 + 字符串键)
foreach ($categories as $Tx => $RxList) {
sort($RxList); // 关键:保证顺序一致,避免 R1R2 与 R2R1 被视为不同键
$key = implode('', $RxList);
if (!isset($tmp[$key])) {
$tmp[$key] = ['values' => $RxList, 'categories' => []];
}
$tmp[$key]['categories'][] = $Tx;
}
// Step 3: 合并结果(NULL 条目 + 聚类条目)
$result = $nulls;
foreach ($tmp as $group) {
$result[] = [
'values' => $group['values'],
'categories' => $group['categories']
];
}
print_r($result);
?>
⚠️ 注意事项与最佳实践
- null 严格比较:务必使用 === null,避免 == null 导致 0、''、false 等误判;
- 排序不可省略:sort() 是字符串键一致性的前提,否则 ['R2','R1'] 和 ['R1','R2'] 将生成不同键;
- 性能考量:若数据量极大(>10k 行),可考虑用 SplFixedArray 替代动态数组,或预计算 value 列表减少重复 sort;
- 扩展性提示:如需支持多级嵌套或权重排序(如优先保留更多 R 的组),可在 $tmp 构建阶段加入长度判断或自定义排序逻辑。
该方案跳出“按 value 直接分组”的思维定式,转而以分类为锚点逆向推导公共实体集,既满足题目中“最大 R 组合优先”的业务规则,又保持代码清晰、可维护性强,是处理复杂多维映射关系的典型范式。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











