2013-05-07 3 views
1

Я работаю над игровым проектом, который нуждается в сортировке и перетасовке многомерного массива. Сначала мне нужно сортировать на основе ставки. Если несколько ставок одинаковы, мне нужно сортировать на основе приоритета. Если ставка & приоритет - это то же самое, что мне нужно перетасовать этими элементами. Например, у нас есть 3 элемента массива в ставке = 0.4 & priority = 4. Идентификаторы: 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) 
); 
+0

проверить этот ответ http://stackoverflow.com/a/15003948/718224 это может вам помочь. –

+0

В вашем примере нет места, где ставки с одинаковыми идентификаторами имеют одинаковые ставки и приоритет – Baba

ответ

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)} 
} 
3

Вы должны взглянуть на 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); 
?> 

перетасовать Я хотел бы добавить дополнительный столбец в многомерный массив под названием «рант», а затем заполнить его со случайным числом, прежде чем использовать Multisort , Затем вы можете добавить 3-й порядок сортировки в этом столбце для перетасовки.

+1

Простой usort достаточно, для сортировки как минимум. Но мне нравится ваша идея добавить случайное число. –

+0

Создание функции для сортировки и ее использования не намного проще, чем указано выше. Сдвиг, потому что есть другой вариант, кажется немного суровым. –

+0

Я не спускал вниз. Но я собираюсь одолжить твою идею, если ты не против. –

0
  • положить элементы, которые нужно перетасовать в массив и удалить их из начального массива до тех пор, пока исходный массив не станет пустым.
  • вызов shuffle на созданном массиве
  • положить перетасованный массив в новый массив с результатами.
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"); 
?> 
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 
    }); 
+0

не первый проверить опечатку? 'Id' должен быть' bid', я думаю? –

+0

Его не .. его оператор if .. он будет работать, только если 'id' то же самое, если бы он не использовал идентификатор для сортировки ....может быть немного запутанным, но посмотрите на него еще раз – Baba

+0

Я думаю, что комментарии, которые вы добавили, меня отбросили. В комментариях упоминается 'bid', в то время как код упоминает' id' –

1

Также на основе @Hugos answer, добавив перетасовать с помощью PHP встроенный в случайном порядке() и диапазон() функции:

<?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. Вероятно, какой-то эффект используемого алгоритма.

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); 
?> 
+0

Это может быть полезно другим, если вы объясните, почему ваш код отличается и как он исправляет проблему. –

Смежные вопросы