1,一种巧妙的办法
<?php
/**
* 根据二维数组元素中的某个field的值,对整个二维数组进行排序
* @param array $arr
* @param string $field
* @param int $desc 是否倒序 0否 1是
* @return array
*/
function sortByField(array $arr, string $field, int $desc = 0) {
if (count($arr) <= 1 || empty($field) || !isset($arr[0][$field])) {
return $arr;
}
//把原数组的key替换成field的值作为新的key
$arr = array_column($arr, null, $field);
//对新数组按照 键 的大小进行排序
$desc ? krsort($arr) : ksort($arr);
return $arr;
}
$a = [
[
'a' => 1,
'b' => '111'
],
[
'a' => 0,
'b' => '000'
],
[
'a' => 3,
'b' => '333'
],
];
$res = sortByField($a, 'a');
var_dump($res);
结果
array(3) {
[0]=>
array(2) {
["a"]=>
int(0)
["b"]=>
string(3) "000"
}
[1]=>
array(2) {
["a"]=>
int(1)
["b"]=>
string(3) "111"
}
[2]=>
array(2) {
["a"]=>
int(3)
["b"]=>
string(3) "333"
}
}
还有一种是手动去建立 field的值 和 value 之间的映射,再对field的值进行排序,然后根据排序和映射,获取到结果。
上面这种方法利用了array_column()的特性,直接建立了这种映射。
2,手动排序
<?php
/**
* 根据二维数组元素中的某个field的值,对整个二维数组进行排序
* @param array $arr
* @param string $field
* @param int $desc 是否倒序 0否 1是
* @return array
*/
function sortByField(array $arr, string $field, int $desc = 0) {
if (count($arr) <= 1 || empty($field) || !isset($arr[0][$field])) {
return $arr;
}
$result = [];
//建立起要排序的field值和原数组key之间的映射关系,此映射数组的键为原数组的field的值,值为原数组的key
$sortFieldKeysMap = array_flip(array_column($arr, $field));
//对field数组进行排序
$sortFieldKeys = array_keys($sortFieldKeysMap);
$desc ? rsort($sortFieldKeys) : sort($sortFieldKeys);
foreach ($sortFieldKeys as $sortFieldKey) {
$result[] = $arr[$sortFieldKeysMap[$sortFieldKey]];
}
return $result;
}
$a = [
[
'a' => 1,
'b' => '111'
],
[
'a' => 0,
'b' => '000'
],
[
'a' => 3,
'b' => '333'
],
];
$res = sortByField($a, 'a');
var_dump($res);
结果
array(3) {
[0]=>
array(2) {
["a"]=>
int(0)
["b"]=>
string(3) "000"
}
[1]=>
array(2) {
["a"]=>
int(1)
["b"]=>
string(3) "111"
}
[3]=>
array(2) {
["a"]=>
int(3)
["b"]=>
string(3) "333"
}
}
这个题目有一个隐含的前提,就是这个二维数组中,每个元素的field的值都是不同的。
如果遇到两个field值是相同的,则如何排序呢?当然,我们可以用引入第二个field字段的值来排序,但仍然会存在相同的,所以只能一直排序下去,到最后,使用原有的key来排序。这种场景就有点像MySQL里面的多字段排序,如果两行记录所有字段的值都相同,则最后只能用主键ID来做最后排序。
来源:oschina
链接:https://my.oschina.net/u/3412738/blog/3217116