Переключать элементы 2d массива - PullRequest
1 голос
/ 14 апреля 2020

У меня проблема: я не могу заставить свой сценарий работать со штрафами , но я заставил его работать с бонусами.

Запуск: двумерный массив пользователей, каждый из которых имеет идентификатор, имя, начальную позицию и модификатор (если модификатор <0 - его бонус; если модификатор> 0 - его штраф).

Как работают модификаторы: например, я есть очередь пользователей Test1, Test2, Test3. Если я дам пользователю Test3 бонус 1, он поменяется местами с пользователем Test 2, и окончательная очередь будет Test1, Test3, Test2. Если я дам ему 2, то он будет первым в очереди.

Наказания работают наоборот. Если я дам пользователю Test1 штраф 1, он будет вторым в очереди. Если я дам ему штраф 3, он будет перемещен в конец очереди.

Это мой рабочий код для бонусов:

<?
$new = array(); $orders = array();

$new[111]['position'] = 1; $new[111]['user'] = 'Test1'; $orders[1] = 111; $new[111]['shift'] = 0;
$new[222]['position'] = 2; $new[222]['user'] = 'Test2'; $orders[2] = 222; $new[222]['shift'] = 0;
$new[333]['position'] = 3; $new[333]['user'] = 'Test3'; $orders[3] = 333; $new[333]['shift'] = 0;
$new[444]['position'] = 4; $new[444]['user'] = 'Test4'; $orders[4] = 444; $new[444]['shift'] = 0;
$new[555]['position'] = 5; $new[555]['user'] = 'Test5'; $orders[5] = 555; $new[555]['shift'] = 0;
$new[666]['position'] = 6; $new[666]['user'] = 'Test6'; $orders[6] = 666; $new[666]['shift'] = 0;
$new[777]['position'] = 7; $new[777]['user'] = 'Test7'; $orders[7] = 777; $new[777]['shift'] = 0;
$new[888]['position'] = 8; $new[888]['user'] = 'Test8'; $orders[8] = 888; $new[888]['shift'] = 0;


//shift function
function bonus($start, $bonus)
{
  global $new, $orders;
  //for bonuses, shift to start, $bonus is negative number
  if ($bonus < 0)
  {
    for ($i = $start; $i > ($start - abs($bonus)); $i--)
    {
      $order_id = intval($orders[$i]);
      $prev = intval($orders[$i - 1]);
      if ($prev != 0)
      {
        $temp = $new[$order_id]['position'];
        $new[$order_id]['position'] = $new[$prev]['position'];
        $new[$prev]['position'] = $temp;
        $orders[$i] = $prev;
        $orders[$i - 1] = $order_id;
      }
    }

  }
  //end for bonuses
}

// Now I set modificator (bonus negative, penalty positive)
$new[555]['shift'] = -2;

// sort by bonuses
$i = 1;
foreach($new as $value)
{
  $order_id = $orders[$i];
  bonus($new[$order_id]['position'], $new[$order_id]['shift']);
  $i++;
}

  // sort 2d array with field position
  usort($new, function($a, $b){
      return $a['position'] <=> $b['position'];
  });

//DATA OUTPUT

$i = 1;
foreach($new as $value)
{
 echo $i . '. ' . $value['user'] . ' ; shift: ' . $value['shift'];
 echo '<br>';
 $i++;
}

?>

На этот код я установил бонус с: $ new [555] ['shift'] = -2;

Таким образом, штраф будет таким: $ new [444] ['shift'] = 3;

Код для штрафов, я думаю должно быть что-то вроде этого:

//for penalty, shift to the end, $bonus positive number
  if ($bonus > 0)
  {
    $total_new = count($new);
    for ($i = $start; $i < ($start + $bonus); $i++)
    {
      $order_id = intval($orders[$i]);
      $next = intval($orders[$i + 1]);
      if ($next < $total_new)
      {
        $temp = $new[$order_id]['position'];
        $new[$order_id]['position'] = $new[$next]['position'];
        $new[$next]['position'] = $temp;
        $orders[$i] = $next;
        $orders[$i + 1] = $order_id;
      }
    }
  }
//end code for penalty

Вот что-то не так с $ orders. Я пробовал много разных типов кода в течение всего дня, включая перечисление массива в порядке asc / des c, но это не сработало корректно ...

PS Я знаю о array_multisort, но мне не нужно Я должен поменять элементы друг с другом.

Опять же: бонус 2 означает, что пользователь должен поменяться местами с предыдущим номером 2 раза. Наказание 3 означает, что пользователь должен поменяться местами со следующим пользователем 3 раза.

...