在PHP中sortingmultidimensional array

我目前正在创build一个sorting方法,它由来自mysql查询的值组成。

以下是该数组的简要说明:

Array ( [0] => Array ( ['id'] = 1; ['countries'] = 'EN,CH,SP'; ) [1] => Array ( ['id'] = 2; ['countries'] = 'GE,SP,SV'; ) ) 

我已经成功地基于数字id值来创build一个正常的usort,但是我宁愿要按照“countries”字段的内容对数组进行sorting(如果它包含setstring,在这种情况下是国家代码),然后由id字段。

下面的代码片段是我如何做到的第一个想法,但是我不知道如何将它合并到一个工作函数中:

 in_array('EN', explode(",",$a['countries']) ); 

你会怎么做?

谢谢!


不幸的是,我真的无处可去。

这是我现在所拥有的,它给我什么,只是错误: 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()

编辑:重新 – 您的评论。 希望这会让你走上正轨。 这个function给予均具有EN或者既不具有EN的元素也具有相同的优先权,或者当具有EN的元素具有调整的优先权。

 usort($array,function ($a, $b) { $ac = strpos($a['countries'],'EN'); $bc = strpos($a['countries'],'EN'); if (($ac !== false && $bc !== false) || ($ac == false && $bc == false)) { return 0; } elseif ($ac !== false) { return 1; } else { return -1; } }); 

另一方面,如果两者都具有EN,那么该function给予相同的优先权,如果有EN,则该function更高,并且如果两者都不具有EN,则进行文本比较。

 usort($array,function ($a, $b) { $ac = strpos($a['countries'],'EN'); $bc = strpos($a['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 } 

更多的编辑!

实际上,我在思考更复杂的sorting问题,并提出了以下解决scheme,供您考虑。 它可以让你定义数字排名基于关键字会出现在国家指数。 这里是代码,包括一个例子:

示例数组

 $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', ), ); 

sorting例程

 $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) { 

请注意,大于已被更改为小于符号。 进行此更改将导致sorting最低的条目被sorting到数组的顶部 。 希望这一切都有帮助!

还请注意!

这段代码将会对你的数组做一个小的改动,因为它将_score元素添加到每个数组中。 希望这不是一个问题,因为通过存储这个值,我实际上能够将速度提高一倍以上(在我的基准testing中,.00038-.00041降至.00016-.00018)。 如果没有,则除去检索caching值的if块,并且每次执行else块的内容,当然除了存储得分值的部分除外。

顺便说一句,这是一个var_export()转储sorting后:

 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, ), ) 

请享用!

最后在PHP.net中find了这个奇妙的function:

  function array_msort($array, $cols) { $colarr = array(); foreach ($cols as $col => $order) { $colarr[$col] = array(); foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); } } $eval = 'array_multisort('; foreach ($cols as $col => $order) { $eval .= '$colarr[\''.$col.'\'],'.$order.','; } $eval = substr($eval,0,-1).');'; eval($eval); $ret = array(); foreach ($colarr as $col => $arr) { foreach ($arr as $k => $v) { $k = substr($k,1); if (!isset($ret[$k])) $ret[$k] = $array[$k]; $ret[$k][$col] = $array[$k][$col]; } } return $ret; } 

这是每个国家的样子:$ array ['countries'] = in_array($ needle,$ haystack); }

 $array = $array = array_msort($array, array('countries'=>SORT_DESC, 'id'=>SORT_ASC)); 

感谢所有的帮助!

你可能会考虑array_walkarray_walk_recursivearray_map ,当它们结合在一起可能会做你想做的事情。

尝试使用array_mulisort 。

查看uasort以查看如何使用用户定义的比较函数。