设置以下内容:
$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行。在到达该位置的过程中,它已经通过第1列传递了4次,在其他2-4列中传递了3次。因此,为了获取迭代索引的虚拟索引,需要将每个列中出现的次数相加,以找出在原始索引中前进了多少个数字。如果超过成员最大数量,则从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);
就是这样:演示,代码片段。
A B C D E F G H I J K L
,并且你想要一个数组A D G J B E H K C F I L
?也就是说,“列”和“行”的概念实际上在数据中并没有被表示出来?(如果是这样的话——你怎么知道有三行四列呢?) - ruakh