javascript网格帮助

时间:2011-02-06 05:19:01

标签: javascript loops grid

我正在研究循环几个网格项目,并希望有人可以帮我找到一种方法来弄清楚如何获得我需要的项目,并且我可能会更好地了解如何访问网格中的项目。所以这是网格。

[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]

这基本上是一个5x5网格,但它可以是任何大小,但我只是用这个例子。我想通过两种方式来解决这个问题。第一个按顺序排列:

0,1,2,3,4,9,14,19,24,23,22,21,20,15,10,5,6,7,8,13,18,17,16,11,12

基本上所做的一切都是从左上角开始绕过外面。我想要循环的下一个方法是通过相同的确切值除了相反的顺序(基本上是在里面而不是在外面)并且实际上考虑这个我现在可以向后循环第一个方法。如果有人能帮助我,那就太棒了。我真的想学习更多关于如何在像这样的疯狂安排中循环项目。

3 个答案:

答案 0 :(得分:1)

此功能

function n(i, w, h)
{
    if (i < w)
        return i;
    if (i < w + h-1)
        return w-1 + (i-w+1)*w;
    if (i < w + h-1 + w-1)
        return w-1 + (h-1)*w - (i - (w + h-1 - 1));
    if (i < w + h-1 + w-1 + h-2)
        return (h - (i - (w + w-1 + h-1 - 2)))*w;
    var r = n(i - (w-1)*2 - (h-1)*2, w-2, h-2);
    var x = r % (w-2);
    var y = Math.floor(r / (w-2));
    return (y+1)*w + (x+1);
}

接受输入

  • i:您正在寻找的项目的索引
  • w:网格宽度
  • h:网格高度

并返回网格的相应元素,假设顺时针方向螺旋遍历。

实现只是检查我们是否位于(i<w)的右侧,右下方(i<w+h-1)等等,对于这些情况,它会明确地计算单元格元素。 如果我们围绕螺旋完成一次单行程,那么它会递归调用以在内部(w-2)*(h-2)网格中找到元素,然后根据原始网格大小提取和调整两个坐标。

对于大网格来说,这比迭代和模拟螺旋步行要快得多,例如计算n(123121, 1234, 3012)是立即的,而完整的网格有3712808个元素,步行123121步需要相当长的时间。 / p>

答案 1 :(得分:0)

这是“行走”方法。效率较低,但有效。

var arr = new Array();
for(var n=0; n<25; n++) arr.push(n);

var coords = new Array(); 

var x = 0;
var y = 0;
for(var i=0; i<arr.length; i++) {
     if( x > 4 ) {
          x = 0;
          y++;
     }

     coords[i] = {'x': x, 'y': y};

     x++;
}

// okay, coords contain the coordinates of each item in arr

// need to move along the perimeter until a collision, then turn.

// start at 0,0 and move east.

var dir = 0; // 0=east, 1=south, 2=west, 3=north.
var curPos = {'x': 0, 'y': 0};
var resultList = new Array();

for(var x=0; x<arr.length; x++) {
     // record the current position in results
     var resultIndex = indexOfCoords(curPos, coords);

     if(resultIndex > -1) {
         resultList[x] = arr[resultIndex];
     }
     else {
         resultList[x] = null;
     }

     // move the cursor to a valid position
     var tempCurPos = movePos(curPos, dir);

     var outOfBounds = isOutOfBounds(tempCurPos, coords);
     var itemAtTempPos = arr[indexOfCoords(tempCurPos, coords)];
     var posInList = resultList.indexOf( itemAtTempPos );

     if(outOfBounds || posInList > -1) {
          dir++;
          if(dir > 3) dir=0;
          curPos = movePos(curPos, dir);
     }
     else {
          curPos = tempCurPos;
     }
}


/* int indexOfCoords
 *
 * Searches coordList for a match to myCoords.  If none is found, returns -1;
 */
function indexOfCoords(myCoords, coordsList) {
    for(var i=0; i<coordsList.length; i++) {
        if(myCoords.x == coordsList[i].x && myCoords.y == coordsList[i].y) return i;
    }
    return -1;
}

/* obj movePos
 *
 * Alters currentPosition by incrementing it 1 in the direction provided.
 * Valid directions are 0=east, 1=south, 2=west, 3=north
 * Returns the resulting coords as an object with x, y.
 */
function movePos(currentPosition, direction) {
    var newPosition = {'x':currentPosition.x, 'y':currentPosition.y};
    if(direction == 0) {
        newPosition.x++;
    }
    else if(direction == 1) {
        newPosition.y++;
    }
    else if(direction == 2) {
        newPosition.x--;
    }
    else if(direction == 3) {
        newPosition.y--;
    }

    return newPosition;
}

/* bool isOutOfBounds
 *
 * Compares the x and y coords of a given position to the min/max coords in coordList.
 * Returns true if the provided position is outside the boundaries of coordsList.
 *
 * NOTE: This is just one, lazy way of doing this.  There are others.
 */
function isOutOfBounds(position, coordsList) {
    // get min/max
    var minx=0, miny=0, maxx=0, maxy=0;
    for(var i=0; i<coordsList.length; i++) {
        if(coordsList[i].x > maxx) maxx = coordsList[i].x;
        else if(coordsList[i].x < minx) minx = coordsList[i].x;

        if(coordsList[i].y > maxy) maxy = coordsList[i].y;
        else if(coordsList[i].y < miny) miny = coordsList[i].y;
    }

    if(position.x < minx || position.x > maxx || position.y < miny || position.y > maxy) return true;
    else return false;
}

这将在一个方向上穿过网格,直到它到达结果数组中的边界或项目,然后顺时针转动。这是非常简陋的,但我认为它可以完成这项工作。你可以简单地扭转它。

以下是一个有效的例子:http://www.imakewidgets.com/test/walkmatrix.html

答案 2 :(得分:0)

您只需要一种表示遍历模式的方法。

给定NxM矩阵(例如5x5),模式为

GENERAL       5x5
-------     -------
N right        5
M-1 down       4
N-1 left       4
M-2 up         3
N-2 right      3
M-3 down       2
N-3 left       2
M-4 up         1
N-4 right      1

这表示向右移动5,向下移动4,向左移动4,向上移动3,向右移动3,向下移动2,向左移动2,向上移动1,向右移动1。每两次迭代后,步长会发生变化。

因此,你可以追踪当前的“步长”和当前方向,同时递减N,M直到你到达终点。

重要提示:请务必记下非方形矩阵的模式,以确定是否适用相同的模式。