我有一个包含多个元素的数组,每个元素都有一个布尔值“ best_match”和一个整数“ score”。
$data = [
["score" => 100, "best_match" => false],
["score" => 90, "best_match" => true], // <<< should be set as first element
["score" => 60, "best_match" => false],
["score" => 40, "best_match" => false],
["score" => 30, "best_match" => false],
];
我如何排序此数组,将best_match => true
的元素设置为第一个元素,然后按其分数对其余元素排序?
这是我尝试使用usort的内容:
usort($data, function ($a, $b) {
if ($a->good_match) {
return 1;
} else {
return $b->score - $a->score;
}
});
它的匹配顺序是:
$matches = [
["score" => 100, "best_match" => false],
["score" => 90, "best_match" => true],
["score" => 60, "best_match" => false],
["score" => 40, "best_match" => false],
["score" => 30, "best_match" => false]
];
/**
Return score, but add big number to score if it is a best match.
*/
function getScore($match) {
$bigNumberIfBestMatch = $match['best_match'] ? 1000 : 0;
return $bigNumberIfBestMatch + $match['score'];
}
usort($matches, function ($a, $b) {
return getScore($b) - getScore($a);
});
*由于此代码对匹配项进行排序,因此我将$data
重命名为$matches
。
usort($data, function ($a, $b) {
if($a["best_match"]){ // Check if the first value is the best match, and return -1, indicating $a is smaller than $b
return -1;
}
else if($b["best_match"]){ // Check if the second value is the best match, and return 1, indicating $b is smaller than $a
return 1;
}
else{ // If both the values are not the best, then sort them based on their score
return $b["score"]-$a["score"];
}
});
??
之后进行另一种比较usort($data, function ($a, $b) {
// Element with true is first else compare based on the difference in score
return $a->best_match < $b->best_match ?? $b->score - $a->score;
});
我还建议太空飞船操作员<=>
而不是计算差值,但两者似乎都可以使用您的测试数据。您提供的数据结构与排序功能不匹配,因此我调整了测试数据:
$data = [ (object) ["score" => 100, "best_match" => false], (object) ["score" => 60, "best_match" => true], (object) ["score" => 60, "best_match" => false], (object) ["score" => 40, "best_match" => false], (object) ["score" => 30, "best_match" => false] ];
如果您使用数组而不是对象,请使用数组访问运算符。
usort($data, function ($a, $b) { return $a['best_match'] < $b['best_match'] ?? $b['score'] <=> $a['score']; });