我有以下数组,我试图按分数排序,然后匹配,然后命名,但我的方法不起作用。谁能明白为什么?
最终的顺序应该是4,3,5。
我使用的usort
位于底部。
[3] => Array
(
[name] => DrayTek Vigor 2130Vn VoIP/WiFi Router
[matches] => Array
(
[0] => voip
)
[score] => 3
)
[4] => Array
(
[name] => DrayTek Vigor 2750n VDSL Wireless Router
[matches] => Array
(
[0] => 2750
)
[score] => 3
)
[5] => Array
(
[name] => DrayTek Vigor 2850Vn VDSL/ADSL VoIP Router
[matches] => Array
(
[0] => voip
)
[score] => 3
)
逻辑
1. all have the same score, so no change in order
2. 4 has 2750 in matches[0] which assuming numbers come before letters, moves 4 up
** the order now should be 4,3,5
3. as 3 and 5 have the same matches[], no change in order
4. 3's name naturally comes before 5 but since its already above, no change
** final order should be 4,3,5
排序结果,先得分最高,然后匹配数组,然后命名
function cmp($a, $b)
{
if ( $a['score'] < $b['score'] )
return 1;
elseif ( $a['score'] > $b['score'] )
return -1;
elseif ( ! array_diff( $a['matches'], $b['matches'] ) )
return 1;
elseif ( ! array_diff( $b['matches'], $a['matches'] ) )
return -1;
elseif ( ($c = strnatcmp( strtolower($a['name']), strtolower($b['name']) ) ) !== 0 )
return $c;
else
return 0;
}
usort( $this->results['rows'], "cmp" );
答案 0 :(得分:0)
你似乎对匹配数组比较的意义有所反转(如果它们相等则返回1,而不是返回0 /让它通过到下一个测试)。因为当它们不相等时你需要一个确定的顺序,也许你应该按匹配数组的长度排序:
function cmp($a, $b)
{
# sort by score
$result = $b['score'] - $a['score'];
# then by number of matches
if ($result == 0) {
$result = count($b['matches']) - count($a['matches']);
}
# if they have the same number of matches but different matches, who wins?
if ($result == 0) {
$result = strnatcasecmp($a['name'], $b['name']);
}
return $result;
}
array_diff
的问题是它返回一个数组。你将这个结果与a和b的订购进行比较是什么?比较函数需要能够在没有任何其他上下文的情况下对任何两个项进行排序。
答案 1 :(得分:0)
找到解决方案
function cmp($a, $b)
{
if ( $a['score'] < $b['score'] )
return 1;
if ( $a['score'] > $b['score'] )
return -1;
if ( count( $a['matches'] ) > count( $b['matches'] ) )
return 1;
if ( count( $a['matches'] ) < count( $b['matches'] ) )
return -1;
natsort( $a['matches'] ); natsort( $b['matches'] );
for ( $i = 0; $i < count( $a['matches'] ); $i++ )
{
if ( ( $c = strnatcasecmp( $b['matches'][$i], $a['matches'][$i] ) ) !== 0)
return $c;
}
if ( ( $c = strnatcasecmp( strtolower($a['name'] ), strtolower( $b['name'] ) ) ) !== 0 )
return $c;
return 0;
}
usort( $this->results['rows'], "cmp" );