0

スコア、一致、名前の順に並べ替えようとしている次の配列がありますが、メソッドが機能していません。誰でも理由がわかりますか?

最終的な順番は 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" );
4

2 に答える 2

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" );
于 2013-02-04T00:48:57.540 に答える
0

一致する配列の比較の意味が逆になっているようです (0 を返す/次のテストに渡す代わりに、等しい場合は 1 を返します)。それらが等しくない場合は明確な順序が必要なので、マッチ配列の長さでソートする必要があるかもしれません:

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 の順序を得るために、その結​​果を何と比較しますか? 比較関数は、配列の残りの部分から他のコンテキストなしで任意の 2 つの項目を順序付けできる必要があります。

于 2013-02-03T16:21:02.120 に答える