Ind*_*ial 5 php arrays usort multidimensional-array
我目前正在创建一个由mysql查询中的值组成的排序方法.
这是阵列的简要视图:
Array
(
[0] => Array
(
['id'] = 1;
['countries'] = 'EN,CH,SP';
)
[1] => Array
(
['id'] = 2;
['countries'] = 'GE,SP,SV';
)
)
Run Code Online (Sandbox Code Playgroud)
我已经成功地根据数字id值进行了正常的操作,但是我更愿意按"countries"字段的内容对数组进行排序(如果它包含一个设置字符串,在这种情况下是一个国家/地区代码),然后由id字段.
以下片段是我对如何做到的第一个想法,但我不知道如何将它合并到一个工作函数中:
in_array('EN', explode(",",$a['countries']) );
Run Code Online (Sandbox Code Playgroud)
你会怎么做?
谢谢!
不幸的是,我真的无处可去.
这就是我现在拥有的东西,它给我的只是错误: 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");
Run Code Online (Sandbox Code Playgroud)
有没有人可能会给我一些如何继续下去的提示?
Der*_*sed 12
就个人而言,我会使用自定义(匿名)功能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;
}
});
Run Code Online (Sandbox Code Playgroud)
另一方面,如果两者都具有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;
}
}
});
Run Code Online (Sandbox Code Playgroud)
再次,希望这将为您提供足够的方向来自行前进.如果您遇到任何问题,请随时发表更多评论,我会尽力提供帮助. 如果你想要将多个属性与重量进行比较,请注意:尝试一个时髦的开关块,例如
$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
}
Run Code Online (Sandbox Code Playgroud)
实际上,我正在考虑更复杂的排序问题,我提出了以下解决方案,供您考虑.它允许您根据将出现在国家/地区索引中的关键字来定义数字排名.这是代码,包括一个例子:
示例数组
$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',
),
);
Run Code Online (Sandbox Code Playgroud)
排序例程
$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;
}
});
Run Code Online (Sandbox Code Playgroud)
注意:此代码将排名最高的entires排序到数组的顶部.如果您想要反向行为,请更改此:
elseif ($aScore > $bScore) {
Run Code Online (Sandbox Code Playgroud)
至
elseif ($aScore < $bScore) {
Run Code Online (Sandbox Code Playgroud)
请注意,大于号已更改为小于号.进行此更改将导致排序最低的条目排序到数组的顶部.希望这一切都有帮助!
此代码将对您的数组进行一些小的更改,因为它将_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,
),
)
Run Code Online (Sandbox Code Playgroud)
请享用!