JavaScript:对角自动排序变量多维数组

这更像是一个与数学相关的问题。

我试图用jQuery创建一个可爱的淡入淡出效果,通过在一定数量的块中分割元素,然后逐渐淡化它们,但是基于另一个数组延迟淡化效果。

所以要创建块表我有两个变量:

var rows = 4, cols = 10; 

这会将元素划分为以下块:

  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 

然后我创建另一个数组来决定块的动画效果。 例如,对于从左到右的对角线动画,此数组看起来像:

 order = [0, 10, 1, 20, 11, 2, 30, 21, 12, 3, 31, 22, 13, 4, 32, 23, 14, 5, 33, 24, 15, 6, 34, 25, 16, 7, 35, 26, 17, 8, 36, 27, 18, 9, 37, 28, 19, 38, 29, 39]; 

对于这个具体案例,它有效:D

我的问题是如何根据块数(行x列)自动创建order数组,而不是手动创建order数组?

谢谢

这样做:

 var arr = []; var rows = 4; var cols = 10; for(var i = 0; i < rows + cols - 1; i++){ for(var j = Math.min(rows, i + 1) - 1; j >= Math.max(0, i - cols + 1); j--){ arr.push((j * cols) + i - j); } } 

小提琴: http : //jsfiddle.net/BmXpy/

编辑:这是我试图解释我是如何想出这个的。 重要的是,使用上面的数字表进行可视化,如果需要,打印并绘制对角线。

首先,想想我们想要什么,它基本上是对角线。 在上面的例子中,第一个对角线是0,然后是10,1,然后是20,11,2,然后是30,21,12,3等。现在,如果你想一下这些对角线有多少,那就是rows + cols - 1 。 这是我们获得第一个循环的地方:

 for(var i = 0; i < rows + cols - 1; i++){ 

现在,忽略一下边界。 在一般情况下(整个中心),这些对角线中的每一个都是“行”长。 而且由于我们想要自下而上,我们需要一个反向循环。 对于内循环,这看起来像这样:

 for(var j = rows - 1; j >= 0; j--){ 

现在,我们必须处理两个边界(左和右)。

对于左边界,如果我们查看长度小于“行”的对角线数量,我们将看到它是rows - 1 。 对于这些对角线,我们将看到每个对角线的长度为i + 1 。 以下内部循环将处理一般情况和左边界:

 for(var j = Math.min(rows, i + 1) - 1; j >= 0; j--){ 

您将看到对于对角线0,这将运行一次,1将运行两次,等等。对于一般情况( i >= rows ),它将运行“行”次。

现在,正确的边界。 如果我们看一下右边的哪些对角线比“行”短,我们将看到它的所有对角线都大于“cols”(在cols为10的示例中,0为索引,即第10行及以上)。 用j >= Math.max(0, i - cols + 1)替换j >= 0将对于一般情况和左边界运行为0,但对于右边界则缩短。 我们得到这个:

 for(var j = Math.min(rows, i + 1) - 1; j >= Math.max(0, i - cols + 1); j--){ 

最后,实际计算每个位置的数量。 i表示对角线, j表示对角线上的数字索引j = 0是最高数字,如果您正在查看已发布的数字表格。 对于j = 0 (顶行数字),数字只是i ,对于顶部下方的每一行,我们需要将数字乘以“cols”以便得到直接低于第一行数的数字,然后数字需要向左调整。 这是通过减去作为行号的j来完成的。 因此,对于j = 1 (第2行),我们需要将数字向左移动(减去1)。 所以我们将i放在第一行的水平位置, + (j * cols)将其向下移动到适当的行然后-j将其调整为对角线(如果您绘制了对角线,则将其追踪到其中一个他们要获得良好的视觉效果)。 我们得到这个:

 (j * cols) + i - j 

把它们放在一起,你得到我上面的最终代码。 希望这有点道理。

还有另一种方法。

 function diagonalized_block (rows, cols) { blocks = []; for (var i = 0; i < rows * cols; i++) { blocks.push(i); } blocks.sort(function (a, b) {return a/cols + a%cols - b/cols - b%cols}); return blocks; } 

这个想法很简单。 编写所有块的明显数组,然后按照您想要的顺序升序的块的函数进行排序。 该函数是x/cols + x%cols 。 这是row + ascending error on diagonal + col 。 所以你首先按照它们所在的对角线排序,然后在对角线上升。

对于其他模式,您必须找到恰好排序的其他函数。 (或者编写一个更复杂的排序函数,完全按照您的意愿执行。)

这里有另一个代码http://jsfiddle.net/paska/FhLnu/3/

 var rows = 4, cols = 10, getValue = function(x, y) { return (y * cols) + x; }, addValue = function(x, y) { $("#arr").append(getValue(x, y) + ", "); }, max = rows + cols - 1, updateRow = 0; for(var i = 0; i < max; i++) { if(i >= rows) updateRow++; for(var x = 0; x <= i; x++) { //$("#arr").append(x + " " + (i - x) + "
"); var row = (i - x), col = x; if(updateRow) { row = row - updateRow; col = col + updateRow; } if(col >= cols) break; if(row >= 0 && col >= 0) addValue(col, row); } }

我知道@kingjiv代码有效,我只是想添加另一种方法。