很多时候,我们需要对一个二维关联数组进行排序,而且这种排序可能不是一次就能排好,打个比方,一份成绩单,首先按照分数倒序排序,在分数相同的情况下,按照学号进行顺序排列;
代码
<?php
uasort($arr, 'my_sort');
function my_sort($a, $b) {
// 全局化排序键
global $firstKey, $secondKey;
// 如果第一排序键对应的值相同
if (intval($a[$firstKey]) == intval($b[$firstKey])) {
// 则按第二排序键进行顺序排列
return (intval($a[$secondKey]) > intval($b[$secondKey])) ? 1 : -1;
} else {
// 否则按第一排序键进行倒序排列
return (intval($a[$firstKey]) > intval($b[$firstKey])) ? -1 : 1;
}
}
?>
测试
$arr = array(
array(
'name'=>'悔创阿里杰克马',
'score'=>'96',
'number'=>'02',
),
array(
'name'=>'普通家庭马化腾,',
'score'=>'96',
'number'=>'01',
),
array(
'name'=>'不知妻美刘强东',
'score'=>'96',
'number'=>'03',
),
array(
'name'=>'一无所有王健林',
'score'=>'90',
'number'=>'05',
),
array(
'name'=>'随便挣钱丁三石',
'score'=>'90',
'number'=>'34',
),
array(
'name'=>'名下无房潘石屹',
'score'=>'100',
'number'=>'11',
),
array(
'name'=>'下周回国贾跃亭',
'score'=>'80',
'number'=>'06',
),
);
// 第一排序键
$firstKey = 'score';
// 第二排序键
$secondKey = 'number';
uasort($arr, 'my_sort');
var_dump($arr);
结果
/opt/wwwroot/test/test3.php:65:
array (size=7)
5 =>
array (size=3)
'name' => string '名下无房潘石屹' (length=21)
'score' => string '100' (length=3)
'number' => string '11' (length=2)
1 =>
array (size=3)
'name' => string '普通家庭马化腾,' (length=24)
'score' => string '96' (length=2)
'number' => string '01' (length=2)
0 =>
array (size=3)
'name' => string '悔创阿里杰克马' (length=21)
'score' => string '96' (length=2)
'number' => string '02' (length=2)
2 =>
array (size=3)
'name' => string '不知妻美刘强东' (length=21)
'score' => string '96' (length=2)
'number' => string '03' (length=2)
3 =>
array (size=3)
'name' => string '一无所有王健林' (length=21)
'score' => string '90' (length=2)
'number' => string '05' (length=2)
4 =>
array (size=3)
'name' => string '随便挣钱丁三石' (length=21)
'score' => string '90' (length=2)
'number' => string '34' (length=2)
6 =>
array (size=3)
'name' => string '下周回国贾跃亭' (length=21)
'score' => string '80' (length=2)
'number' => string '06' (length=2)
总结
1, 对已有方法的运用掌握还不够,总想着自己造轮子,需要再强化;
2, 这个方法还的封装性还不够好,不能使用匿名函数;
自己写的复杂未完结待修改版本
/*
* 二维数组排序
* $arr 需要处理的二维数组
* $row 需要排序的列
* $type 倒序还是升序
* 一次排序保留键值对对应关系,二次排序不保留键值对应关系
*/
function array_sort($arr, $firstRow, $secondRow, $type='asc') {
$firstRowResult = array();
$secondRowResult = array();
// 先按第一排序键排列好
if (!empty($arr)) {
foreach ($arr as $key=>$value) {
// 在二维数组的所有元素中第一排序键对应的所有值
$firstRowArray[$key] = $value[$firstRow];
}
if ($type == 'asc') {
asort($firstRowArray);
} else {
arsort($firstRowArray);
}
reset($firstRowArray);
foreach ($firstRowArray as $k=>$v) {
$firstRowResult[$k] = $arr[$k];
}
}
// 再进行第二排序键的排列
// 如果第一排序键对应了相同的值,则按第二排序键进行排序
// 在第一排序键相同值数组中,用第二排序键的顺序来决定二维数组的键的排序
// 如何取出第一排序键相同值的数组
if ($secondRow == '') {
return $firstRowResult;
} else {
print 11111111;
var_dump($firstRowResult);
$firstRowArray = array();
// 取出所有值,不保留键值对关系
// $firstRowResult = array_values($firstRowResult);
foreach ($firstRowResult as $key=>$value) {
// 在二维数组的所有元素中第一排序键对应的所有值
$firstRowArray[$key] = $value[$firstRow];
}
var_dump($firstRowArray);
foreach ($firstRowArray as $firstRowKey=>$firstRowValue) {
// 第一排序键的值出现的所有键
$firstRowSameValueKeys = array_keys($firstRowArray, $firstRowValue);
var_dump($firstRowSameValueKeys);
// 第一排序键的值出现的次数
$len = count($firstRowSameValueKeys);
// 如果第一排序键的值只出现过一次
if ($len == 1) {
print '跳过1';
$secondRowResult[] = $firstRowValue;
continue;
// 如果出现过多次,则有重复值
} else {
// 重复值的键都是挨在一起的
// 在重复值内部按第二排序键进行排序
$secondRowArray = array();
// 对所有拥有相同值的第一键进行遍历
foreach ($firstRowSameValueKeys as $firstRowSameValueKey) {
// 取出二维数组中第一键的值相同的所有元素
$secondRowArray[$firstRowSameValueKey] = $firstRowResult[$firstRowSameValueKey];
}
var_dump($secondRowArray);
// 将第一键的值相同的所有元素组成的数组按第二键进行排序,返回排序后的第一键的值相同的所有元素组成的数组
$secondRowArray = array_sort($secondRowArray, $secondRow, '', $type);
var_dump($secondRowArray);
$secondRowResult = array_merge($secondRowResult, $secondRowArray);
var_dump($secondRowResult);
}
}
return $secondRowResult;
}
}
$result = array_values($result);