2011-02-06 42 views
0

我正在循环浏览几个网格项目,并希望有人能够帮助我找到一种方法来弄清楚如何到达我需要的项目,并且可能我会更好地了解如何访问项目网格。所以这里是网格。javascript grid help

[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 

基本上所有这些都是从左上方开始。下一个我想循环的方法是通过相同的确切值,除了相反的顺序(基本上是在内部而不是在外部),并且实际上想到了这一点,现在我可以通过向后循环第一种方法。如果任何人都可以帮助我,这将是伟大的。我真的想要了解更多关于如何在这样的疯狂安排中循环的项目。

+0

什么是“从里到外”的输出?是0,5,10..etc还是24,23,22等? – 2011-02-06 06:11:23

+0

就像我之前说过的,它是我列出的确切值,除了相反的顺序,所以12,11,16 ...等 – ngreenwood6 2011-02-06 06:19:24

回答

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)等,对于这些情况下,它显式计算单元格元素。 如果我们绕螺旋线完成一次单程,那么它会递归地调用它自己以在网格内部找到元素,然后考虑原始网格大小提取并调整两个坐标。

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

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

+0

我没有测试这个,但我感谢你添加你的解决方案,我的问题,虽然它似乎并不完整(缺少功能)。 – ngreenwood6 2011-02-06 15:47:04

+0

缺失的函数应该易于编写,但是当我在普通计算机上时,我可能会添加它们。困难的部分是这个概念,我把它覆盖了。 – Craig 2011-02-06 16:44:28

0

你只需要一个方式来表示遍历模式。

鉴于N×M矩阵(例如5×5),该模式是

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 up,1 right。每两次迭代之后步长都会改变。

因此,您可以在减少N,M的同时跟踪当前的“步长”和当前的方向,直到达到最后。

重要提示:请务必记下非方形矩阵的图案,以查看是否应用了相同的图案。