如何使用usort对多维数组按连续关联值排序?
解决多维数组的连续行程链式排序问题
嘿,我明白你遇到的问题了——用usort()来处理这种链式行程排序确实不太靠谱,因为它的核心是两两元素的比较逻辑,而你要的是构建连续的依赖链:每个元素的from必须衔接前一个的to,找不到衔接项的就作为新链的起点。这种场景下,直接排序行不通,得换一种“构建链式结构”的思路。
核心思路
我们不需要排序,而是要:
- 快速定位每个
from对应的元素,方便后续查找衔接项; - 找出所有没有前驱的起始节点(即
from值从未出现在任何元素的to里的项); - 从每个起始节点出发,顺着
from→to的关系,逐个拼接出完整的行程链。
具体实现代码(PHP)
假设你的原始数组是这样的:
$trips = [ ['from' => 'B', 'to' => 'C', 'data' => 'Trip 2'], ['from' => 'A', 'to' => 'B', 'data' => 'Trip 1'], ['from' => 'D', 'to' => 'E', 'data' => 'Trip 4'], ['from' => 'C', 'to' => 'D', 'data' => 'Trip 3'], ['from' => 'F', 'to' => 'G', 'data' => 'Trip 5'], ];
步骤1:构建快速查找映射表
把数组转成以from为键的关联数组,这样能O(1)时间找到某个to对应的下一个元素:
$tripMap = []; foreach ($trips as $trip) { $tripMap[$trip['from']] = $trip; }
步骤2:筛选所有起始节点
找出那些没有前驱的项——也就是from值没有出现在任何元素to字段里的元素:
// 收集所有已存在的to值 $allToValues = array_column($trips, 'to'); // 筛选起始节点 $startNodes = array_filter($trips, function($trip) use ($allToValues) { return !in_array($trip['from'], $allToValues); });
步骤3:构建连续行程链
从每个起始节点出发,顺着from→to的关系拼接链条:
$sortedTrips = []; $visited = []; // 防止循环引用导致死循环 foreach ($startNodes as $currentTrip) { $chain = []; // 循环拼接直到找不到下一个节点 while ($currentTrip && !isset($visited[$currentTrip['from']])) { $visited[$currentTrip['from']] = true; $chain[] = $currentTrip; // 查找下一个节点:当前节点的to作为下一个节点的from $currentTrip = $tripMap[$currentTrip['to']] ?? null; } // 把这条链加入最终结果 $sortedTrips = array_merge($sortedTrips, $chain); }
运行后,$sortedTrips就是你想要的连续行程结构了:
[ ['from' => 'A', 'to' => 'B', 'data' => 'Trip 1'], ['from' => 'B', 'to' => 'C', 'data' => 'Trip 2'], ['from' => 'C', 'to' => 'D', 'data' => 'Trip 3'], ['from' => 'D', 'to' => 'E', 'data' => 'Trip 4'], ['from' => 'F', 'to' => 'G', 'data' => 'Trip 5'], ]
为什么usort()不行?
usort()的比较函数只能判断两个元素的相对顺序,但没法处理链式依赖。比如元素A→B→C,当比较A和C的时候,你没法直接从这两个元素本身判断谁在前谁在后(它们没有直接的from/to关联),所以usort()的两两比较逻辑在这里就失效了,自然得不到你想要的连续结构。
内容的提问来源于stack exchange,提问作者mshifo
相关产品推荐
相关产品推荐

