就个人而言,我会结合使用自定义(匿名)函数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;
}
}
});
再次,希望这会给你足够的方向,让你自己前进。如果您有任何问题,请随时发表更多评论,我会尽力提供帮助。 如果您要将多个属性与重量进行比较,请注意:尝试一个时髦的开关块,例如
$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;
// and so on
}
更多编辑!
其实,我在复杂排序的问题上思考的比较多,我想出了下面的解决方案,供大家参考。它将允许您根据出现在国家/地区索引中的关键字定义数字排名。这是代码,包括一个示例:
示例数组
$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 元素添加到每个数组。希望这不是问题,因为通过存储这个值,我确实能够将速度提高一倍以上(在我的基准测试中,0.00038-.00041 下降到 0.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,
),
)
享受!