JavaScript:自动对可变多维数组进行对角排序

Posted

技术标签:

【中文标题】JavaScript:自动对可变多维数组进行对角排序【英文标题】:JavaScript: Automatically order a variable multi-dimensional array diagonally 【发布时间】:2011-08-15 13:36:46 【问题描述】:

这更像是一道数学题。

我正在尝试使用 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 数组?

谢谢

【问题讨论】:

是否总是用于从左到右的对角线动画? 不,我也想做这个 r-t-l 对角线,或者从中心旋转等。但是现在我想了解如何在这种情况下做到这一点,l-t-r 对角线 【参考方案1】:

这样就可以了:

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,等等。现在如果你想想这些对角线有多少,它是 @987654323 @。这就是我们得到第一个循环的地方:

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 &gt;= rows),它将运行“行”次。

现在,正确的边界。如果我们查看右侧的哪些对角线比“rows”短,我们将看到所有对角线都大于“cols”(在 cols 为 10、0 索引的示例中,即第 10 行及以后)。用j &gt;= Math.max(0, i - cols + 1) 替换j &gt;= 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(第二行),我们需要将数字左移一(减1)。所以我们有i 用于第一行的水平位置,+ (j * cols) 将其向下移动到适当的行,然后 -j 将其调整为对角线(如果您绘制了对角线,请为其中一个跟踪以获得良好的视觉效果)。我们得到这个:

(j * cols) + i - j

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

【讨论】:

@kingjiv:非常好!顺便说一下,建议使用 '[]' 而不是 'Array()' 漂亮!但请向我解释一下,i &lt; rows + cols 之后我完全迷路了 :) @diego 好点,已更新。试图改掉这个习惯。 @alex 我今晚回家后会整理一个解释。 @alex,编辑了我的答案,试图解释它。希望它在某种程度上有用。【参考方案2】:

还有另一种方法。

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。所以你首先按照它们在哪个对角线上排序,然后在对角线上升序。

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

【讨论】:

【参考方案3】:

这里还有一个代码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) + "<br />");
        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 代码有效,我只是想添加另一种方法。

【讨论】:

以上是关于JavaScript:自动对可变多维数组进行对角排序的主要内容,如果未能解决你的问题,请参考以下文章

Javascript:对多维数组进行排序

如何在javascript中对多维数组进行排序

php多维数组自定义排序 uasort()

php多维数组自定义排序 uasort()

传递可变大小的多维数组

数组实验