对多维数组进行排序和随机排序

时间:2013-05-07 08:02:59

标签: php arrays sorting multidimensional-array

我正在开发游戏项目,需要对多维数组进行排序和混洗。首先,我需要根据出价进行排序。如果多个出价相同,我需要根据优先级进行排序。如果出价&优先级都是相同的意味着我需要洗牌这些元素。例如,我们在bid = 0.4&中有3个数组元素。优先级= 4。 Id是102,103& 104.应该改组这些数组元素的位置。

array(
    array('id' => 101, 'bid' => 0.5, 'priority' => 5),
    array('id' => 102, 'bid' => 0.4, 'priority' => 4),
    array('id' => 103, 'bid' => 0.4, 'priority' => 4),
    array('id' => 104, 'bid' => 0.4, 'priority' => 4),
    array('id' => 105, 'bid' => 0.3, 'priority' => 5),
    array('id' => 106, 'bid' => 0.3, 'priority' => 5),
    array('id' => 107, 'bid' => 0.2, 'priority' => 5),
    array('id' => 108, 'bid' => 0.7, 'priority' => 5),
    array('id' => 108, 'bid' => 0.1, 'priority' => 4)
);

7 个答案:

答案 0 :(得分:4)

你应该看看array_multisort来做到这一点。该页面上有关于如何对多维数组进行排序的示例

<?php
// Obtain a list of columns
foreach ($data as $key => $row) {
  $bid[$key]  = $row['bid'];
  $prio[$key] = $row['priority'];
}

array_multisort($bid, SORT_ASC, $prio, SORT_ASC, $data);
?>

要进行随机播放,我会在名为“rand”的多维数组中添加一个额外的列,然后在使用多重排序之前用随机数填充它。然后,您可以在该列上添加第3个排序顺序以进行混洗。

答案 1 :(得分:2)

基于关于使用随机权重的想法@Hugo's answer

$array = array(
    array('id' => 101, 'bid' => 0.5, 'priority' => 5),
    array('id' => 102, 'bid' => 0.4, 'priority' => 4),
    array('id' => 103, 'bid' => 0.4, 'priority' => 4),
    array('id' => 104, 'bid' => 0.4, 'priority' => 4),
    array('id' => 105, 'bid' => 0.3, 'priority' => 5),
    array('id' => 106, 'bid' => 0.3, 'priority' => 5),
    array('id' => 107, 'bid' => 0.2, 'priority' => 5),
    array('id' => 108, 'bid' => 0.7, 'priority' => 5),
    array('id' => 108, 'bid' => 0.1, 'priority' => 4)
);
function cmp(&$a, &$b) {                                     # notice the use of & in function signature
    if ($a['bid'] - $b['bid']) {
        return $a['bid'] - $b['bid'] > 0 ? 1 : -1;           # bid is different, sort using bid
    } else if ($a['priority'] - $b['priority']) {
        return $a['priority'] - $b['priority'] > 0 ? 1 : -1; # priority is different, sort using priority
    } else {
        if (isset($a['rw']) == false) {
            $a['rw'] = rand(1, 100);                         # assign random tie breaker
        } 
        if (isset($b['rw']) == false) {
            $b['rw'] = rand(1, 100);                         # assign random tie breaker
        } 
        if ($a['rw'] - $b['rw']) {
            return $a['rw'] - $b['rw'] > 0 ? 1 : -1;         # sort using random weight
        } else {
            return 0;
        }
    }
}
usort($array, 'cmp');
var_dump($array);

<强>输出

array(9) {
[0]=>array(3) {["id"]=>int(108) ["bid"]=>float(0.1) ["priority"]=>int(4)}
[1]=>array(3) {["id"]=>int(107) ["bid"]=>float(0.2) ["priority"]=>int(5)}
[2]=>array(4) {["id"]=>int(106) ["bid"]=>float(0.3) ["priority"]=>int(5) ["rw"]=>int(70)}
[3]=>array(4) {["id"]=>int(105) ["bid"]=>float(0.3) ["priority"]=>int(5) ["rw"]=>int(73)}
[4]=>array(4) {["id"]=>int(103) ["bid"]=>float(0.4) ["priority"]=>int(4) ["rw"]=>int(29)}
[5]=>array(4) {["id"]=>int(104) ["bid"]=>float(0.4) ["priority"]=>int(4) ["rw"]=>int(67)}
[6]=>array(4) {["id"]=>int(102) ["bid"]=>float(0.4) ["priority"]=>int(4) ["rw"]=>int(80)}
[7]=>array(3) {["id"]=>int(101) ["bid"]=>float(0.5) ["priority"]=>int(5)}
[8]=>array(3) {["id"]=>int(108) ["bid"]=>float(0.7) ["priority"]=>int(5)}
}

答案 2 :(得分:1)

Usort对于这种情况是理想的http://www.php.net/manual/en/function.usort.php
定义执行比较的功能

<?php
function cmp($a, $b)
{
    if ($a['bid'] == $b['bid']) {
        if ($a['priority'] == $b['priority']) return 0;
        return ($a['priority'] < $b['priority']) ? -1 : 1;
    }
    return ($a['bid'] < $b['bid']) ? -1 : 1;
}

usort($data, "cmp");
?>

答案 3 :(得分:1)

您可以使用usort

usort($array,function ($a, $b) {

            if ($a['id'] == $b['id']) {
                if ($a['priority'] == $b['priority'] && $a['bid'] == $b['bid']) {
                    $pos = array(-1,0,1);
                    return $pos[mt_rand(0, 2)]; // shurffle
                }

                $a = $a['priority'];
                $b = $b['priority'];

                return ($a == $b) ? 0 : (($a > $b) ? - 1 : 1); // sorty by priority
            }

            // First i need to sort based on bid
            $a = $a['id'];
            $b = $b['id'];
            return ($a == $b) ? 0 : (($a < $b) ? - 1 : 1); //sort by bid id
    });

答案 4 :(得分:1)

同样基于@Hugos answer,使用内置shuffle()和range()函数的PHP添加shuffle:

<?php
$data=array(

array('id'=>101,'bid'=>0.5,'priority'=>5),
array('id'=>102,'bid'=>0.4,'priority'=>4),
array('id'=>103,'bid'=>0.4,'priority'=>4),
array('id'=>104,'bid'=>0.4,'priority'=>4),
array('id'=>105,'bid'=>0.3,'priority'=>5),
array('id'=>106,'bid'=>0.3,'priority'=>5),
array('id'=>107,'bid'=>0.2,'priority'=>5),
array('id'=>108,'bid'=>0.7,'priority'=>5),
array('id'=>108,'bid'=>0.1,'priority'=>4)
);


$rand=range(0,count($data)-1);
shuffle($rand);

foreach ($data as $key => $row) {
  $bid[$key]  = $row['bid'];
  $prio[$key] = $row['priority'];
}

array_multisort($bid, SORT_ASC, $prio, SORT_ASC, $rand, SORT_ASC, $data);

我首先尝试在排序之前简单地改组数组,但由于某些未知原因,排序似乎也在id上排序。可能是使用算法的一些影响。

答案 5 :(得分:0)

<?php

foreach ($data as $key => $row) {
  //just create a random field
  $data[$key]['randSort']= rand(1,999999);
  $sameRand[$key] = $data[$key]['randSort'];

  $bid[$key]  = $row['bid'];
  $prio[$key] = $row['priority'];
}

array_multisort($bid, SORT_ASC, $prio, SORT_ASC, $sameRand, SORT_ASC, $data);
?>

答案 6 :(得分:-1)

  • 将要洗牌的元素放入数组中,然后将它们从初始数组中删除,直到初始数组为空。
  • 在创建的数组
  • 上调用shuffle
  • 将洗牌后的数组放入带有结果的新数组中。