Intereting Posts
PDO отказывается удалить строку данных (в конкретной таблице) WooCommerce – Автоматическое добавление или автоматическое удаление продукта в корзину Удаление элементов из массива внутри foreach Как вставить HTML-форму в базу данных MySQL? Как добавить предмет в пурпурные пурпурные jQuery Загрузка содержимого Div с текущей страницы на другую страницу Как определить, имеет ли строка в нем разрыв строки? Как вы запрещаете людям переходить на страницу, которая должна использоваться как страница входа? Массив, возвращающий значение null, многие для многих. Laravel Работает среда Symfony2, среда prod дает ошибку 404 Невозможно изменить информацию заголовка о статической функции Строка извлечения регулярных выражений между двумя фигурными фигурными скобками Получить имя папки laravel view Проблема с получением данных из нескольких полей в один массив Использование RESTful API для динамических веб-сайтов

PHP-Как соединить элементы в массиве на основе условия

Как я могу собрать элементы в массиве? Скажем, у меня есть массив бойцов . И я хочу связать их по их весам . Бойцы с самыми близкими весами должны быть спарены как лучший матч . Но если они находятся в одной команде, их не следует спаривать .

  • ** — Команда 1 – **
  • Истребитель A Вес 60
  • Истребитель В Вес 65
  • ** – Команда 2 – **
  • Истребитель С Вес 62
  • Истребитель D Вес 60
  • ** – Команда 3 – **
  • Истребитель E Вес 64
  • Истребитель F Вес 66

Вывод:

  • Истребитель VS Истребитель D
  • Истребитель B VS Fighter F
  • Истребитель C VS Истребитель E

Я изучал эту тему и нашел нечто подобное, но не совсем: случайные, но уникальные пары, с условиями

Было бы очень полезно помочь. Заранее спасибо!

Solutions Collecting From Web of "PHP-Как соединить элементы в массиве на основе условия"

Мне очень понравился ваш вопрос, поэтому я сделал полную надежную версию.

<?php header("Content-type: text/plain"); error_reporting(E_ALL); /** * @class Fighter * @property $name string * @property $weight int * @property $team string * @property $paired Fighter Will hold the pointer to the matched Fighter */ class Fighter { public $name; public $weight; public $team; public $paired = null; public function __construct($name, $weight, $team) { $this->name = $name; $this->weight = $weight; $this->team = $team; } } /** * @function sortFighters() * * @param $a Fighter * @param $b Fighter * * @return int */ function sortFighters(Fighter $a, Fighter $b) { return $a->weight - $b->weight; } $fighterList = array( new Fighter("A", 60, "A"), new Fighter("B", 65, "A"), new Fighter("C", 62, "B"), new Fighter("D", 60, "B"), new Fighter("E", 64, "C"), new Fighter("F", 66, "C") ); usort($fighterList, "sortFighters"); foreach ($fighterList as $fighterOne) { if ($fighterOne->paired != null) { continue; } echo "Fighter $fighterOne->name vs "; foreach ($fighterList as $fighterTwo) { if ($fighterOne->team != $fighterTwo->team && $fighterTwo->paired == null) { echo $fighterTwo->name . PHP_EOL; $fighterOne->paired = $fighterTwo; $fighterTwo->paired = $fighterOne; break; } } } 
  1. Во-первых, бойцы хранятся в классах, что упрощает присвоение им свойств (если вы этого не сделали, я призываю вас делать!)
  2. Создайте массив бойцов и назначьте им имена, веса и команды.
  3. usort() массив по весу (используя usort() и функцию сортировки sortFighters() для сортировки по весовому свойству каждого элемента.
  4. Итерации по массиву и сопоставление на основе:
    1. Истребитель еще не согласован
    2. Истребитель два не в той же команде, что истребитель один
    3. Истребитель два уже не соответствует
  5. Когда совпадение найдено, сохраните указатель объекта каждого соответствующего бойца друг к другу (так что он больше не равен нулю, плюс вы можете получить доступ к каждой из пар бойцов, перейдя в $fighterVariable->paired )
  6. Наконец, напечатайте результат.

Это просто расширение ответа Истины на основе комментариев:

Первое, что я сделал бы по-другому, – это основное отслеживание игроков.

 $unassignedPlayers = $fighterList; 

Чем алгоритм будет работать так: подготовьте список команд (если вы используете базу данных, используйте SELECT DISTINCT или GROUP BY teams.id ):

 $teams = array(); foreach( $fighterList as $fighter){ $teams[] = $figter->team; } $teams = array_unique( $teams); 

Затем нам понадобится метод, который будет разделять массив бойцов (скажем, у нас есть команды {A,A,B,B,C,C} мы хотим разбить на {A,A} , {B,B,C,C} ):

 // Don't use string type declaration, it's just ilustrating function splitFighters( array $input, string $team){ $inteam = array(); $outteam = array(); foreach( $input as $fighter){ if( $figter->team == $team){ $inteam[] = $fighter; } else { $outteam[] = $fighter; } } return array( $inteam, $outteam); } 

Теперь, когда у нас есть это, мы можем создать функцию, которая будет сортировать членов команды:

 function assignFighters( array &$input, array $teams, array &$output){ // Nothing to work with? if( !count( $input)){ return true; } // No team left and still unassigned players, that fatal error if( !cont( $teams)){ throw new Exception( 'Unassigned players occurred!'); } // Shift team $team = array_shift( $teams); // Split into in and out team list( $inteam, $outteam) = splitFighters( $input, $team); // Inteam is already empty (let's say all players were assigned before) // Just go deeper (where's DiCaprio?) if( !count( $inteam) && count( $teams)) { return assignFighters( $input, $teams, $output) } // There're unassigned and nonassignable players in this team // This is error and we'll have to deal with it later if( !count($outteam)){ $input = $inteam; // Propagate unassigned players to main return false; } // Sort both teams by fighters weight // Uses Truth's comparison function usort($inteam, "sortFighters"); usort($outteam, "sortFighters"); // Fig = Fighter while( $fig1 = array_shift( $inteam)){ // Are there any players to work with if( !count( $outteam)){ array_unshift( $inteam, $fig1); $input = $inteam; // Propagate unassigned players to main return false; } // Assign players to each other $fig2 = array_shift( $outteam); $fig1->paired = $fig2; $fig2->paired = $fig1; // This will propagate players to main nicely $output[] = $fig1; $output[] = $fig2; } // Still here? Great! $inteam is empty now // $outteam contains all remaining players $input = $outteam; return assignFighters( $input, $teams,$output); } 

До этого момента вы могли бы использовать алгоритм Истины, но это должно иметь лучшее соответствие веса и представляет собой то, что вы намереваетесь более четко, но в любом случае теперь вы получаете $unassignedPlayers в работу:

 $assignedPlayers = array(); $state = assignFighters( $unassignedPlayers, $teams, $assignedPlayers); // Note: $state === !(bool)count($unassignedPlayers) // should evaluate as true, otherwise I'm having an error in algorithm 

Итак, что теперь … Если у вас $state === false resp. count( $unassignedPlayers) > 0 что-то пошло не так, и нам нужно применить магию. Как эта магия будет работать:

 // Keep the trace of swapped players so we don't end up in endless loop $swappedPlayers = array(); // Browse all unassigned players while( $fig1 = array_shift( $unassignedPlayers)){ // Store as swapped $swappedPlayers[] = $fig1; // At first check whether there's not unassigned player in the different team // this shouldn't occur in first iteration (all fighters should be from one team // in the beginning) but this is most effective part of this method foreach( $unassignedPlayers as $key => $fig2){ if( $fig2->team != $fig1->team){ $fig1->pair = $fig2; $fig2->pair = $fig1; continue; } } // No luck, normal magic required list( $inteam, $outteam) = splitFighters( $assignedPlayers, $fig1->team); $fig2 = null; // I like my variables initialized, this actually quite important // Now select someone from $outteam you will want to swap fights with. // You may either iterate trough all players until you find best weight // match or select it random, or whatever, I'll go with random, // it's your job to implement better selection $i = 1000; // Limit iterations while(($i--) > 1){ $key1 = array_rand( $outteam, 1); if( $outteam[$key]->team == $fig1->team){ continue; // No point in swapping fit team member } // No recursive swaps if( in_array( $outteam[$key], $swappedPlayers)){ continue; } // This may speed things really up: // That means we'll get rid of 2 players due to foreach loop at the beggining // However I'm not sure how this condition will really work if( $outteam[$key]->pair->team == $fig1->team){ continue; } // Store matched fighter $fig2 = $outteam[$key]; // Unset pair from another fighter $fig2->pair->pair = null; // Find the pair in $assignedPlayers and move it to $unassignedPlayers $key = array_search( $fig2->pair, $assignedPlayers); if( $key === false){ throw new Exception( 'Cannot find pair player'); } unset( $assignedPlayers[$key]); $unassignedPlayers[] = $fig2->pair; $swappedPlayers[] = $fig2->pair; // Remove pair from self $fig2->pair = null; $swappedPlayers[] = $fig2; break; // hh, try forgetting this one :) } // This shouldn't be happening if( $fig2 === null){ throw new Exception( 'Didn\'t find good match in 1000 iterations.'); } // Ok now just make matches as go to the next iteration $fig1->pair = $fig2; $fig2->pair = $fig1; // And store those $assignedPlayers[] = $fig1; $assignedPlayers[] = $fig2; } 

Я написал все это из головы (это был вызов), протестировать его и оставить заметки в комментариях, пожалуйста 🙂

Сортируйте массив по весу. Затем у вас будут пары весов, которые близки друг к другу.