个人而言,我会使用一个自定义(匿名)函数与
usort()
结合使用。
编辑:关于你的评论。希望这能帮助你找到正确的方向。这个函数给予同时具有EN或都没有EN的元素相等的优先级,或者在只有一个元素具有EN时调整优先级。
usort($array,function ($a, $b) {
$ac = strpos($a['countries'],'EN');
$bc = strpos($b['countries'],'EN');
if (($ac !== false && $bc !== false) || ($ac == false && $bc == false)) {
return 0;
}
elseif ($ac !== false) {
return 1;
}
else {
return -1;
}
});
这个函数,另一方面,如果两者都有EN,则给予相等的优先级,如果其中一个有EN,则给予更高的优先级,如果两者都没有EN,则进行文本比较。
usort($array,function ($a, $b) {
$ac = strpos($a['countries'],'EN');
$bc = strpos($b['countries'],'EN');
if ($ac !== false && $bc !== false)) {
return 0;
}
elseif ($ac !== false) {
return 1;
}
elseif ($bc !== false) {
return -1;
}
else {
if ($a['countries'] == $b['countries']) {
return 0;
}
elseif($a['countries'] > $b['countries']) {
return 1;
}
else {
return -1;
}
}
});
希望这次能给你足够的指引,让你能够自己继续前进。如果你遇到任何问题,随时发表更多评论,我会尽力帮助你。如果你想要比较多个属性的权重,请尝试使用一个有趣的switch块,例如。
$ac = array_flip(explode(',',$a['countries']));
$bc = array_flip(explode(',',$b['countries']));
switch (true) {
case array_key_exists('EN',$ac) && !array_key_exists('EN',$bc):
return 1;
case array_key_exists('DE',$ac) && !array_key_exists('EN',$bc) && !array_key_exists('EN',$bc):
return 1;
}
#更多修改!#
实际上,我更多地考虑了复杂排序的问题,并提出了以下解决方案,供您考虑。它将允许您根据在国家索引中出现的关键词来定义数字排名。以下是代码,包括一个示例:
示例数组
$array = array(
array(
'countries' => 'EN,DE,SP',
),
array(
'countries' => 'EN,CH,SP',
),
array(
'countries' => 'DE,SP,CH',
),
array(
'countries' => 'DE,SV,SP',
),
array(
'countries' => 'EN,SP,FR',
),
array(
'countries' => 'DE,FR,CH',
),
array(
'countries' => 'CH,EN,SP',
),
);
排序程序
$rankings = array(
'EN' => 10,
'SP' => 8,
'FR' => 7,
'DE' => 5,
'CH' => 3,
'SV' => 1,
);
usort($array, function (&$a, &$b) use ($rankings) {
if (isset($a['_score'])) {
$aScore = $a['_score'];
}
else {
$aScore = 0;
$aCountries = explode(',',$a['countries']);
foreach ($aCountries as $country) {
if (isset($rankings[$country])) {
$aScore += $rankings[$country];
}
}
$a['_score'] = $aScore;
}
if (isset($b['_score'])) {
$bScore = $b['_score'];
}
else {
$bScore = 0;
$bCountries = explode(',',$b['countries']);
foreach ($bCountries as $country) {
if (isset($rankings[$country])) {
$bScore += $rankings[$country];
}
}
$b['_score'] = $bScore;
}
if ($aScore == $bScore) {
return 0;
}
elseif ($aScore > $bScore) {
return -1;
}
else {
return 1;
}
});
注意:此代码将把
排名最高的条目排序到数组的顶部。如果您想要相反的行为,请更改此处:
elseif ($aScore > $bScore) {
到
elseif ($aScore < $bScore) {
请注意,大于号已被更改为小于号。进行这个更改将导致数组中排名最低的条目被排序到顶部。希望这一切对你有所帮助!
还要注意!这段代码会对你的数组进行一个小的更改,即为每个数组添加一个_score元素。希望这不会成为问题,因为通过存储这个值,我成功地将速度提高了一倍以上(从.00038-.00041降到.00016-.00018,根据我的基准测试)。如果有问题,请删除检索缓存值的if块,并让else块的内容每次都执行,当然除了存储分数值的部分。
顺便说一下,这是数组排序后的var_export()转储结果:
array (
0 => array (
'countries' => 'EN,SP,FR',
'_score' => 25,
),
1 => array (
'countries' => 'EN,DE,SP',
'_score' => 23,
),
2 => array (
'countries' => 'EN,CH,SP',
'_score' => 21,
),
3 => array (
'countries' => 'CH,EN,SP',
'_score' => 21,
),
4 => array (
'countries' => 'DE,SP,CH',
'_score' => 16,
),
5 => array (
'countries' => 'DE,FR,CH',
'_score' => 15,
),
6 => array (
'countries' => 'DE,SV,SP',
'_score' => 14,
),
)
享受吧!
ORDER BY country, id
? - Gordon