1

I am working on gaming project, which needs sort and shuffle multidimensional array. First i need to sort based on bid. If multiple bids are same i need to sort based on priority. If bid & priority both are same means I need to shuffle those elements. For example we have 3 array elements in bid=0.4 & priority=4. Id's are 102,103 & 104. These array element position should be shuffled.

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)
);
4

7 回答 7

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”的多维数组中添加一个额外的列,然后在使用 multisort 之前用随机数填充它。然后,您可以在该列上添加第三个排序顺序以进行改组。

于 2013-05-07T08:07:37.463 回答
2

基于想法@Hugo's answer about using random weight:

$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)}
}
于 2013-05-07T08:27:50.880 回答
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");
?>
于 2013-05-07T08:15:26.503 回答
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
    });
于 2013-05-07T08:16:16.353 回答
1

同样基于@Hugos answer,使用 PHP 内置的 shuffle() 和 range() 函数添加 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 排序。可能使用的算法的一些效果。

于 2013-05-07T08:46:25.983 回答
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);
?>
于 2017-09-27T14:01:47.770 回答
-1
  • 将要洗牌的元素放入一个数组中,并将它们从初始数组中移除,直到初始数组为空。
  • 调用shuffle创建的数组
  • 将洗牌后的数组放入带有结果的新数组中。
于 2013-05-07T08:08:35.127 回答