我正在尝试使用多维数组执行与mySQL查询“SELECT * FROM table ORDER BY field1,field2,...”相同的操作:
$Test = array(
array("a"=>"004", "n"=>"03"),
array("a"=>"003", "n"=>"02"),
array("a"=>"001", "n"=>"02"),
array("a"=>"005", "n"=>"01"),
array("a"=>"001", "n"=>"01"),
array("a"=>"004", "n"=>"02"),
array("a"=>"003", "n"=>"01"),
array("a"=>"004", "n"=>"01")
);
function msort(&$array, $keys){
array_reverse($keys);
foreach($keys as $key){
uasort($array, sortByKey);
}
//
function sortByKey($A, $B){
global $key;
$a = $A[$key];
$b = $B[$key];
if($a==$b) return 0;
return ($a < $b)? -1 : 1 ;
}
}
//
msort($Test, array("a","n"));
//
foreach($Test as $t){
echo('<p>'.$t["a"].'-'.$t["n"].'</p>');
}
我的理论是:如果我将多次乘法排序为最重要键的不太重要的键,我会按照mySQL查询的顺序排序。
但是php正在返回“警告:uasort()要求参数2是有效的回调函数,找不到函数'sortByKey',或者在第23行的/Library/WebServer/Documents/www/teste.array_sort.php中找到无效的函数名“(uasort line)
这是一个简单的订单功能,我缺少什么?
答案 0 :(得分:6)
从根本上说,我们将使用与解释here相同的方法,我们只是使用可变数量的键来执行此操作:
/**
* Returns a comparison function to sort by $cmp
* over multiple keys. First argument is the comparison
* function, all following arguments are the keys to
* sort by.
*/
function createMultiKeyCmpFunc($cmp, $key /* , keys... */) {
$keys = func_get_args();
array_shift($keys);
return function (array $a, array $b) use ($cmp, $keys) {
return array_reduce($keys, function ($result, $key) use ($cmp, $a, $b) {
return $result ?: call_user_func($cmp, $a[$key], $b[$key]);
});
};
}
usort($array, createMultiKeyCmpFunc('strcmp', 'foo', 'bar', 'baz'));
// or
usort($array, createMultiKeyCmpFunc(function ($a, $b) { return $a - $b; }, 'foo', 'bar', 'baz'));
这大约等同于SQL ORDER BY foo, bar, baz
。
当然,如果每个密钥都需要不同类型的比较逻辑,并且您无法对所有密钥使用通用strcmp
或-
,那么您将返回与解释{{3}相同的代码}。
答案 1 :(得分:4)
这是我编写的一些类似代码的代码:
uasort($array,function($a,$b) {
return strcmp($a['launch'],$b['launch'])
?: strcmp($a['tld'],$b['tld'])
?: strcmp($a['sld'],$b['sld']);
});
首先比较launch
,然后是tld
,然后是sld
,这有点滥用负数是真实的(只有零是假的)这一事实。您应该能够轻松地根据自己的需要进行调整。
答案 2 :(得分:0)
这将完成这项工作,感谢您的贡献!
function mdsort(&$array, $keys){
global $KeyOrder;
$KeyOrder = $keys;
uasort($array, cmp);
}
function cmp(array $a, array $b) {
global $KeyOrder;
foreach($KeyOrder as $key){
$res = strcmp($a[$key], $b[$key]);
if($res!=0) break;
}
return $res;
}
//
mdsort($Test, array("a","n"));
这段代码有点难看,但我相信它可能会更好 - 也许是一个类来解决将数组传递给“cmp”函数的问题。但它是一个起点,您可以使用它与任意数量的键进行排序。
答案 3 :(得分:0)
PHP7.4的箭头语法消除了以前使列顺序进入[177.00547411 177.00728148 177.00435833 176.99671953 176.98440208
176.96746426 176.94598429 176.92005866 176.88980009 176.85533528
176.81680257 176.77434952]
[177.00547411 177.00615453 177.00667867 177.00704644 177.00725779
177.00731269 177.00721115 177.00695318 177.00653883 177.00596817
177.00524129 177.00435833]
[177.00725779 177.00727941 177.00729586 177.00730713 177.00731323
177.00731417 177.00730993 177.00730051 177.00728593 177.00726617
177.00724125 177.00721115]
[177.00731323 177.00731379 177.00731417 177.00731438 177.00731443
177.0073143 177.00731399 177.00731352 177.00731288 177.00731207
177.00731108 177.00730993]
[177.00731438 177.0073144 177.00731442 177.00731443 177.00731443
177.00731443 177.00731442 177.00731441 177.00731439 177.00731436
177.00731433 177.0073143 ]
[177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443]
[177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443 177.00731443 177.00731443 177.00731443
177.00731443 177.00731443]
[177.00731443]
范围所必需的大部分代码膨胀。
代码:(Demo)
usort()
我认为这是编写任务脚本的一种非常简洁的方式。您可以从$orderBy = ['a', 'n'];
usort($Test, fn($a, $b) =>
array_map(fn($v) => $a[$v], $orderBy)
<=>
array_map(fn($v) => $b[$v], $orderBy)
);
var_export($Test);
和$a
作为单独的数组生成指定的列值,并在它们之间编写太空飞船运算符。
如果没有使用箭头语法,则该片段会显得更加粗大。
代码:(Demo)
$b
太空船操作员将遍历相应的数据对($orderBy = ['a', 'n'];
usort($Test, function($a, $b) use ($orderBy) {
return
array_map(function($v) use ($a){
return $a[$v];
}, $orderBy)
<=>
array_map(function($v) use ($b){
return $b[$v];
}, $orderBy);
});
var_export($Test);
与[0]
,然后[0]
与[1]
,依此类推),直到达到非零值为止评估,直到用尽比较数组。