PHP含Null值数组排序:保留结构并生成连续位置序号
搞定PHP数组的动态位置+默认顺序排序问题
嘿,我明白你现在遇到的问题了——你有一个固定结构的数组,部分元素从数据库拿到了位置值,剩下的是null,想用array_multisort排序但结果不符合预期,想要让有指定位置的元素先占坑,剩下的按默认顺序填充空缺位置对吧?
问题拆解
先把需求再理清楚,避免走偏:
- 你的数组有固定默认顺序:
Amazon | Google | Ebay | Microsoft | Alibaba - 数据库返回的位置值都是≥1的,没拿到的元素
position是null - 最终要实现:有位置的按数值排,没位置的按默认顺序填剩下的空位,整个数组按
position升序排列,还要保留原数组的键值结构
之前用array_multisort直接排的话,null会被排在前面,肯定达不到你要的效果,得换个思路来处理。
解决方案
我分几步来实现,逻辑清晰还容易维护:
完整代码示例
// 初始化默认结构的数组 $data = [ 'Amazon' => ['position' => null], 'Google' => ['position' => null], 'Ebay' => ['position' => null], 'Microsoft' => ['position' => null], 'Alibaba' => ['position' => null] ]; // 模拟从数据库获取位置值 $data['Google']['position'] = 1; $data['Alibaba']['position'] = 4; // 第一步:定义默认顺序(这是核心!决定空缺位置的填充顺序) $defaultOrder = ['Amazon', 'Google', 'Ebay', 'Microsoft', 'Alibaba']; // 第二步:分离已有位置和待填充的元素,同时记录已用的位置 $positionedItems = []; $toFillItems = []; $usedPositions = []; foreach ($data as $key => $item) { if ($item['position'] !== null) { $positionedItems[$key] = $item; $usedPositions[] = $item['position']; } else { $toFillItems[$key] = $item; } } // 第三步:找出1到总元素数中没被使用的空缺位置 $allPossiblePositions = range(1, count($defaultOrder)); $emptyPositions = array_diff($allPossiblePositions, $usedPositions); sort($emptyPositions); // 确保空位是按升序排列的 // 第四步:按默认顺序给待填充元素分配空位 $fillIndex = 0; foreach ($defaultOrder as $key) { if (isset($toFillItems[$key])) { $toFillItems[$key]['position'] = $emptyPositions[$fillIndex]; $fillIndex++; } } // 第五步:合并数组并按position升序排序 $combinedData = array_merge($positionedItems, $toFillItems); // 提取所有position字段用于排序 $sortKeys = array_column($combinedData, 'position'); array_multisort($sortKeys, SORT_ASC, $combinedData); // 看看结果 print_r($combinedData);
代码说明
- 默认顺序数组:
$defaultOrder一定要和你初始数组的默认结构一致,它决定了哪些元素优先填充空位。 - 元素分离:把有位置和没位置的元素分开,同时记下已经被用了的位置,避免重复分配。
- 空位分配:先找出所有可能的位置(1到元素总数),去掉已用的,剩下的按顺序分给待填充的元素。
- 最终排序:合并后用
array_column提取所有position值,再用array_multisort按升序排列,就得到你要的结果了。
运行结果
Array ( [Google] => Array ( [position] => 1 ) [Amazon] => Array ( [position] => 2 ) [Ebay] => Array ( [position] => 3 ) [Alibaba] => Array ( [position] => 4 ) [Microsoft] => Array ( [position] => 5 ) )
小优化
如果以后你要加新的元素或者调整默认顺序,只需要修改$defaultOrder和初始化的$data数组就行,逻辑部分不用动,扩展性拉满~
内容的提问来源于stack exchange,提问作者Linesofcode
相关产品推荐
相关产品推荐

