Как отсортировать массив PHP численно по последовательному шаблону

Спасибо за поиск,

У меня есть массив PHP $array = array(1,1,1,2,3,2,3,4,5,4,4,4,5,1,2,2,3); и я пытаюсь отсортировать его в повторяющемся последовательном порядке числового порядка с самыми большими наборами в первую очередь.

В приведенном выше массиве у меня самое высокое значение 5, которое появляется дважды, поэтому первые два набора будут 1,2,3,4,5 затем он вернется ко второму, наивысшему значению и т. д.

Я хотел бы закончить с 1,2,3,4,5,1,2,3,4,5,1,2,3,4,1,2,4,

Любые указатели в правильном направлении будут с благодарностью.

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

0

Решение

Вы можете использовать только линейную логику для сортировки с использованием функций php. Вот оптимизированный способ заполнения структур данных. Его можно использовать для потоков, генераторов или чего-либо еще, что вы можете повторять и сравнивать.

$array = array(1,1,1,2,3,2,3,4,5,4,4,4,5,1,2,2,3);
sort($array);
$chunks = [];
$index = [];
foreach($array as $i){
if(!isset($index[$i])){
$index[$i]=0;
}
if(!isset($chunks[$index[$i]])){
$chunks[$index[$i]]=[$i];
} else {
$chunks[$index[$i]][] = $i;
}
$index[$i]++;
}
$result = call_user_func_array('array_merge', $chunks);
print_r($result);
0

Другие решения

Вот моя попытка очень ручного цикла с использованием процесса, идея в том, чтобы просто отсортировать числа в контейнеры для array_unshifting. Я уверен, что это ужасно, и я хотел бы, чтобы кто-то сделал это в пять строк или меньше 🙂

$array = array(1,1,1,2,3,2,3,4,5,4,4,4,5,1,2,2,3);
sort($array);
// Build the container array
$numbers = array_fill_keys(array_unique($array),array());
// Assignment
foreach( $array as $number )
{
$numbers[ $number ][] = $number;
}

// Worker Loop
$output = array();
while( empty( $numbers ) === false )
{
foreach( $numbers as $outer => $inner )
{
$output[] = array_shift( $numbers[ $outer ] );
if( empty( $numbers[ $outer ] ) )
{
unset( $numbers[ $outer ] );
}
}
}

var_dump( $output );
1

Я думаю, что я смотрю на это не как на проблему сортировки, а на чередование значений из нескольких списков, так что вместо того, чтобы придумывать наборы различных чисел, я бы сделал наборы тот же самый число.

Поскольку нет разницы между одним 1 и другим, все, что вам действительно нужно, это подсчитать, сколько раз каждый из них появляется. Оказывается, PHP может сделать это для вас aaray_count_values.

$sets = array_count_values ($input);

Затем мы можем убедиться, что наборы в порядке, отсортировав по ключу:

ksort($sets);

Теперь мы перебираем наши множества, считая, сколько раз мы вывели каждое число. Как только мы «опустошим» набор, мы удалим его из списка, и как только у нас не останется наборов, все будет готово:

$output = [];
while ( count($sets) > 0 ) {
foreach ( $sets as $number => $count ) {
$output[] = $number;
if ( --$sets[$number] == 0 ) {
unset($sets[$number]);
}
}
}

Этот алгоритм может быть адаптирован для случаев, когда значения фактически различны, но могут быть помещены в наборы, так как значение каждого набора должно быть списком, а не счетчиком. Вместо — вы бы использовали array_shift, а затем проверяли, была ли длина набора равной нулю.

1

<?php

$array = array(1,1,1,2,3,2,3,4,5,4,4,4,5,1,2,2,3);
sort($array);

while($array) {
$n = 0;
foreach($array as $k => $v) {
if($v>$n) {
$result[] = $n = $v;
unset($array[$k]);
}
}
}

echo implode(',', $result);

Выход:

1,2,3,4,5,1,2,3,4,5,1,2,3,4,1,2,4
0
По вопросам рекламы [email protected]