Настройка следующего:
$array = range('A', 'M');
$columns = 4;
$length = count($array);
print_matrix($array, $columns);
, который выводит каждый элемент и его ключ по индексу (строка и столбец), а также порядок элементов сверху:
One row - A B C D E F G H I J K L M
A[ 0] B[ 1] C[ 2] D[ 3]
E[ 4] F[ 5] G[ 6] H[ 7]
I[ 8] J[ 9] K[10] L[11]
M[12]
связанный код javascript может быть легко преобразован в PHP.Однако, если вы внимательно посмотрите на этот вопрос / ответ, станет ясно, что он работает только с полными строками, как с моей предыдущей попыткой:
function callback_sort($array, $columns)
{
$sort = function($columns)
{
return function($a, $b) use ($columns)
{
$bycol = ($a % $columns) - ($b % $columns);
return $bycol ? : $a - $b;
};
};
uksort($array, $sort(4));
return $array;
}
Вывод:
One row - A E I M B F J C G K D H L
A[ 0] E[ 4] I[ 8] M[12]
B[ 1] F[ 5] J[ 9] C[ 2]
G[ 6] K[10] D[ 3] H[ 7]
L[11]
Итакпросто функция, представленная в другом вопросе, не работает.
Но так как массив уже отсортирован, вам не нужно сортировать его снова, а просто изменить порядок или элементы.Но какой порядок?Если матрица не полная, например, n x n
полностью заполнена, для каждого столбца необходимо рассчитать новый индекс.Взятый пример с 13 элементами (A-M
) дает следующее распределение строк на столбец:
column: 1 2 3 4
rows: 4 3 3 3
Таким образом, для каждого столбца значение отличается.Например, по индексу 12 13-й элемент находится в 4-й строке.На пути к этой позиции она была пройдена 4 раза через столбец 1 и 3 раза в других столбцах 2-4.Таким образом, чтобы получить виртуальный индекс итерированного индекса, вам нужно сложить, как часто вы были в каждом столбце, чтобы выяснить, сколько чисел в исходном индексе вы ожидали.Если вы превысите максимальное число членов, вы продолжите с 0.
Таким образом, это можно было бы решить итеративно, продвигаясь вперед по каждому индексу, чтобы распределить вычисления по индексам:
Index 0:
No column: 0
Index 1:
1x in column is which has 4 rows: 4
Index 2:
1x in column 1 (4 rows) and 1x in other columns (3 rows): 4 + 3
... и так далее.Если виртуальный индекс превышает 12, он начинается с 0, например, для 5-го элемента (индекс 4) виртуальный индекс будет рассчитывать 13:
Index 4:
1x 4 rows and 3x 3 rows = 13 (4 + 9)
13 > 12 => 1 (13 - 12)
Теперь заполняя новый массив, начиная с виртуальногоиндекс 0
и каждый раз с соответствующим смещением (посмотрите, в каком столбце вы находитесь, добавьте количество строк в этом столбце, при необходимости оберните его) получится желаемый результат:
One row - A E H K B F I L C G J M D
A[ 0] E[ 4] H[ 7] K[10]
B[ 1] F[ 5] I[ 8] L[11]
C[ 2] G[ 6] J[ 9] M[12]
D[ 3]
Написано вкод, это просто foreach
по сравнению с исходными индексами.Поддерживая также индекс ключей, это работает с любым массивом, даже с строковыми ключами:
$floor = floor($length/$columns);
$modulo = $length % $columns;
$max = $length-1;
$virtual = 0;
$keys = array_keys($array);
$build = array();
foreach($keys as $index => $key)
{
$vkey = $keys[$virtual];
$build[$vkey] = $array[$vkey];
$virtual += $floor + ($index % $columns < $modulo);
($virtual>$max) && $virtual %= $max;
}
print_matrix($build, $columns);
И все: Demo , Gist .