Взял код кирик за отправную точку и переписал последнюю часть. Не понравилось уж очень, что три вложенных цикла было. Теперь - один, но кода кажется больше стало. +, наверно, стало менее понятно, вдобавок
Ну да спрашивайте, чего непонятно)) Объясню, пока здесь сижу.
PHP |
function cmp($a, $b) { $ca = count($a); $cb = count($b); if($ca == $cb) return 0; return ($ca > $cb) ? -1 : 1; }
function needPush($iteration, $total, &$hostArray, &$currCount) { if ($iteration == 0) return true; $hostIndex = key($hostArray); if ($hostIndex == 0) return true; if (empty($currCount)) $currCount = sizeof($hostArray); $k = $hostIndex / $iteration; echo $k . ' - ' . ($currCount / $total) . '<br />'; if ($k <= $currCount / $total) return true; return false; }
$array = array(); for($i = 0, $c = count($mails); $i < $c; $i++) { $host = ltrim(strstr($mails[$i], '@'), '@'); $array[$host][] = $mails[$i]; } usort($array, 'cmp');
$total = sizeof($mails); $hostCounts = array(); $result = array();
for ($i = 0, reset($array); $i < $total { $curr = current($array); if ($curr === false) $curr = reset($array);
if (needPush($i, $total, $curr, $hostCount[key($array)])) { $result[] = current($curr); if (next($array[key($array)]) === false) array_splice($array, key($array), 1); $i++; } else next($array);
} echo '<pre>'; print_r($result); echo '</pre>'; |
UPD: пару слов все таки скажу тем, кто будет разбираться. Принцип строится на том, что каждый массив имеет свой указатель (итератор). То есть сбор массива получается просто грамотным передвижением указателей + обработкой текущего положения указателей (для определения, нужно ли добавлять адрес в конечный массив).