用棘手的条件对多维数组进行排序

时间:2019-09-17 12:40:04

标签: php multidimensional-array

我是php的新手。我正在尝试对具有某些条件的多维数组进行排序,但是我不知道从哪里开始。

用户数组

Array
(
    [0] => Array
        (
            [uid] => 1
            [Fname] => Kcir
            [Lname] => Nayr
            [wins] => 12
            [scoreGuess] => 45
            [totalScore] => 26
        )

    [1] => Array
        (
            [uid] => 2
            [Fname] => Doe
            [Lname] => John
            [wins] => 12
            [scoreGuess] => 35
            [totalScore] => 26
        )
    [2] => Array
        (
            [uid] => 3
            [Fname] => Greg
            [Lname] => Cuenca
            [Nickname] => Greg
            [wins] => 11
            [scoreGuess] => 21
            [totalScore] => 26
        )

    [3] => Array
        (
            [uid] => 4
            [Fname] => Kenneth
            [Lname] => Agee
            [wins] => 12
            [scoreGuess] => 34
            [totalScore] => 26
        )
)

首先,我需要按 wins 降序对用户进行排序,然后,如果有与 wins 并列的用户,则被绑定的用户将通过 > scoreGuess ,但有条件。如果 scoreGuess totalScore 上最接近的用户,则该用户将排名第一。

例如:用户 1 2 3 与获胜者相关 12 ,totalScore为< strong> 26 。

用户1 的得分猜为 45
用户2 的得分猜为 35
用户4 的得分猜为 34


因此,排名第一的是用户4 ,因为他的得分得分最接近。

我已经尝试过此代码,但是无法正常工作。

function compareUsers($a, $b)
{
            if($a['wins'] > $b['wins'])
            {
                return -1;
            }
            else if ($a['wins'] == $b['wins']) {
                $a_diff = (int) $a['totalScore'] - (int)$a['scoreGuess'];
                $b_diff = (int) $b['totalScore'] - (int) $b['scoreGuess'];

                if ( $a_diff >= 0 && $b_diff >= 0 ) {
                    if ( $a_diff < $b_diff ) {
                        return -1;
                    }
                } else if ( $a_diff >= 0 && $b_diff < 0 ) {
                    return 0;
                } else {
                    return 1;
                }
            }
            else
            {
                return 1;
            }
}

usort($users, "compareUsers");

输出:

Array
(
    [0] => Array
        (
            [uid] => 1
            [Fname] => Kcir
            [Lname] => Nayr
            [wins] => 12
            [scoreGuess] => 45
            [totalScore] => 26
        )

    [1] => Array
        (
            [uid] => 2
            [Fname] => Doe
            [Lname] => John
            [wins] => 12
            [scoreGuess] => 35
            [totalScore] => 26
        )
    [2] => Array
        (
            [uid] => 4
            [Fname] => Kenneth
            [Lname] => Agee
            [wins] => 12
            [scoreGuess] => 34
            [totalScore] => 26
        )
    [3] => Array
        (
            [uid] => 3
            [Fname] => Greg
            [Lname] => Cuenca
            [Nickname] => Greg
            [wins] => 11
            [scoreGuess] => 21
            [totalScore] => 26
        )
)

2 个答案:

答案 0 :(得分:2)

使用usort尝试以下解决方案,当获胜次数不同时,按获胜次数排序。当获胜次数相等时,将使用totalScore和scoreGuess之间的差异进行排序。

$array = [
    0 => [    
        'uid' => 1,
        'Fname' => 'Kcir',
        'Lname' => 'Nayr',
        'wins' => 12,
        'scoreGuess' => 45,
        'totalScore' => 26,
    ],
    1 => [
        'uid' => 2,
        'Fname' => 'Doe',
        'Lname' => 'John',
        'wins' => 12,
        'scoreGuess' => 35,
        'totalScore' => 26,
    ],
    2 => [
        'uid' => 3,
        'Fname' => 'Greg',
        'Lname' => 'Cuenca',
        'Nickname' => 'Greg',
        'wins' => 11,
        'scoreGuess' => 21,
        'totalScore' => 26,
    ],
    3 => [
        'uid' => 4,
        'Fname' => 'Kenneth',
        'Lname' => 'Agee',
        'wins' => 12,
        'scoreGuess' => 34,
        'totalScore' => 26,
    ],
];

usort($array, function($prev, $next) {
     if ($next['wins'] == $prev['wins']) {
          return abs($prev['scoreGuess'] - $prev['totalScore']) <=> abs($next['scoreGuess'] - $next['totalScore']);
     } else {
          return $next['wins'] <=> $prev['wins'];
     }
});

结果是:

Array
(
    [0] => Array
        (
            [uid] => 4
            [Fname] => Kenneth
            [Lname] => Agee
            [wins] => 12
            [scoreGuess] => 34
            [totalScore] => 26
        )

    [1] => Array
        (
            [uid] => 2
            [Fname] => Doe
            [Lname] => John
            [wins] => 12
            [scoreGuess] => 35
            [totalScore] => 26
        )

    [2] => Array
        (
            [uid] => 1
            [Fname] => Kcir
            [Lname] => Nayr
            [wins] => 12
            [scoreGuess] => 45
            [totalScore] => 26
        )

    [3] => Array
        (
            [uid] => 3
            [Fname] => Greg
            [Lname] => Cuenca
            [Nickname] => Greg
            [wins] => 11
            [scoreGuess] => 21
            [totalScore] => 26
        )

)

Demo

答案 1 :(得分:2)

好的,您可以像下面这样使它更简单:

usort($arr,function($data1,$data2){
    if($data1['wins'] != $data2['wins']) return -1 * ($data1['wins'] - $data2['wins']);
    return abs($data1['scoreGuess'] - $data1['totalScore']) - abs($data2['scoreGuess'] - $data2['totalScore']);
});

演示: https://3v4l.org/KCuf9

  • 我们查看集合的wins与其他集合的wins是否相等。
  • 如果它们不相等,我们将两者的差值乘以-1以降序返回。
  • 如果它们相等,则取scoreGuesstotalScore之间的差的绝对值之差。