如何不使用PHP内置函数按my_id对多维数组排序?
PHP多维数组自定义排序(无内置函数)
需求
对给定的PHP多维数组,不使用内置排序函数,按以下规则排序:
- 按子元素
my_id升序排列 - 相同
my_id的元素,按variation_id降序排列
原数组
$my_array = array( '51171#2' => array( 'my_id' => 51171, 'variation_id' => 2, ), '143516#2' => array( 'my_id' => 143516, 'variation_id' => 2, ), '396346#2' => array( 'my_id' => 396346, 'variation_id' => 2, ), '143516#1' => array( 'my_id' => 143516, 'variation_id' => 1, ), '396344#2' => array( 'my_id' => 396344, 'variation_id' => 2, ), '396346#1' => array( 'my_id' => 396346, 'variation_id' => 1, ), '396344#1' => array( 'my_id' => 396344, 'variation_id' => 1, ), );
期望输出
$output_arr = array( '143516#2' => array( 'my_id' => 143516, 'variation_id' => 2, ), '143516#1' => array( 'my_id' => 143516, 'variation_id' => 1, ), '396344#2' => array( 'my_id' => 396344, 'variation_id' => 2, ), '396344#1' => array( 'my_id' => 396344, 'variation_id' => 1, ), '396346#2' => array( 'my_id' => 396346, 'variation_id' => 2, ), '396346#1' => array( 'my_id' => 396346, 'variation_id' => 1, ), '51171#2' => array( 'my_id' => 51171, 'variation_id' => 2, ), );
尝试的错误代码及输出
错误代码
$result = []; foreach($my_array as $key => $source){ foreach($my_array as $key1 => $source1){ if(($source['my_id'] < $source1['my_id'])) { $result[$key1]= $source1; } } } echo '<pre>'; print_r($result);
错误输出
Array ( [143516#2] => Array ( [my_id] => 143516 [variation_id] => 2 ) [396346#2] => Array ( [my_id] => 396346 [variation_id] => 2 ) [143516#1] => Array ( [my_id] => 143516 [variation_id] => 1 ) [396344#2] => Array ( [my_id] => 396344 [variation_id] => 2 ) [396346#1] => Array ( [my_id] => 396346 [variation_id] => 1 ) [396344#1] => Array ( [my_id] => 396344 [variation_id] => 1 ) )
问题分析:原代码逻辑混乱,仅通过遍历赋值实现,既未处理相同my_id的排序规则,还丢失了51171#2元素,完全不符合需求。
正确解决方案
采用冒泡排序实现自定义规则排序,逻辑清晰且符合要求:
// 将原关联数组转为带键的索引数组,方便交换操作 $arr = array_map(null, array_keys($my_array), $my_array); $length = count($arr); // 冒泡排序核心逻辑 for ($i = 0; $i < $length - 1; $i++) { for ($j = 0; $j < $length - $i - 1; $j++) { $current = $arr[$j][1]; $next = $arr[$j+1][1]; // 排序规则: // 1. 当前my_id > 下一个my_id,交换位置(升序) // 2. my_id相同,当前variation_id < 下一个variation_id,交换位置(降序) if ( $current['my_id'] > $next['my_id'] || ($current['my_id'] == $next['my_id'] && $current['variation_id'] < $next['variation_id']) ) { $temp = $arr[$j]; $arr[$j] = $arr[$j+1]; $arr[$j+1] = $temp; } } } // 重新组装回原关联数组格式 $result = []; foreach ($arr as $item) { $result[$item[0]] = $item[1]; } // 输出结果 echo '<pre>'; print_r($result);
代码解释
- 先把原关联数组转为
[键, 值]形式的索引数组,既保留原键名,又方便冒泡排序时交换位置。 - 外层循环控制排序轮次,内层循环比较相邻元素:
- 优先比较
my_id,若当前元素my_id更大则交换,实现升序排列。 - 若
my_id相同,比较variation_id,若当前元素variation_id更小则交换,实现降序排列。
- 优先比较
- 排序完成后,重新组装回原关联数组格式,保留原键名。
运行后输出结果完全符合期望。
内容的提问来源于stack exchange,提问作者Ranveer
相关产品推荐
相关产品推荐

