我目前正在创建一种排序方法,该方法由mysql查询的值组成。
这是数组的简要视图:
Array ( [0] => Array ( ['id'] = 1; ['countries'] = 'EN,CH,SP'; ) [1] => Array ( ['id'] = 2; ['countries'] = 'GE,SP,SV'; ) )
我已经成功地基于数字id值进行了正常的排序,但是我想按“国家/地区”字段的内容对数组进行排序(如果在这种情况下包含设置的字符串和国家/地区代码),然后通过id字段。
以下代码段是我的第一个想法,但我不知道如何将其合并到工作功能中:
in_array('EN', explode(",",$a['countries']) );
你会怎么做?
谢谢!
不幸的是,我真的一无所获。
这是我目前拥有的东西,它给我的只有错误: uasort() [function.uasort]: Invalid comparison function
uasort() [function.uasort]: Invalid comparison function
function compare($a, $b) { global $usercountry; if ( in_array($usercountry, $a['countries']) && in_array($usercountry, $a['countries']) ) { $return = 0; } else if (in_array($usercountry, $a['countries'])) { $return = 1; } else { $return = -1; } return $return; } $array= usort($array, "compare");
有谁可以给我提示如何进行操作吗?
我个人将与结合使用自定义(匿名)函数usort()。
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; } });
注意:此代码会将排序 最高的整体排序到array的顶部 。如果您想要反向行为,请更改此:
elseif ($aScore > $bScore) {
至
elseif ($aScore < $bScore) {
请注意,大于符号已更改为小于符号。进行此更改将导致 排名最低的条目排在数组的顶部 。希望所有这些都对您有所帮助!
此代码将对您的数组进行一些小的更改,因为它将_score元素添加到每个数组。希望这不是问题,因为通过存储该值,我确实能够使速度提高两倍以上(在我的基准测试中,.00038-.00041降至.00016-.00018)。如果不是,请删除if检索缓存值的块,并让else块的内容每次执行,当然存储分数值的部分除外。
if
else
顺便说一下,这是var_export()数组排序后的转储:
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, ), )
请享用!