Estoy intentando obtener todos los índices cerca de un índice determinado en una matriz 2d. actualmente tengo:
function getTileNear(x,y){ var out = []; out.push([x-1,y-1]); out.push([x,y-1]); out.push([x-1,y]); out.push([x+1,y+1]); out.push([x,y+1]); out.push([x+1,y]); out.push([x-1,y+1]); out.push([x+1,y-1]); return out; }No me importan los índices que están fuera de la matriz, solo quiero una forma más eficiente de hacerlo.
function getTileNear(x,y){ let out = [], steps = [1,0,-1] steps.forEach(i => steps.forEach(j => !(i == 0 && j == 0) && out.push([x+i,y+j]))) return out; }Usando bucles for...
function getTileNear(x,y){ let out = [], steps = [1,0,-1]; for (let i of steps) { for (let j of steps) { !(i == 0 && j == 0) && out.push([x+i,y+j]) } } return out; }Si la salida está destinada a usarse en un algoritmo en serie (no necesita una matriz diferente para cada llamada), entonces, al no crear una nueva matriz cada vez, puede calcularla más rápido:
function initTileNear(){ var out = new Array(8); for(var i=0;i<8;i++) out[i]=[0,0]; return out; } var arr = initTileNear(); function getTileNear(x,y){ var ctr=0; for(var j=0;j<=1;j++) for(var i=-1;i<=1;i++) if(!(i===0 && j===0)) { arr[ctr][0]=x+i; arr[ctr][1]=y+j; ctr++; } return arr; } for(var i=0;i<500;i++) { var test = getTileNear(i*2,i*2+1); }esto es 300% más rápido que la versión original que recrea una nueva matriz cada vez.
Con un código un poco más largo, se vuelve más rápido:
function initTileNear(){ var out = new Array(8); for(var i=0;i<8;i++) out[i]=[0,0]; return out; } var arr = initTileNear(); function getTileNear(x,y){ arr[0][0]=x-1; arr[0][1]=y-1; arr[1][0]=x; arr[1][1]=y-1; arr[2][0]=x+1; arr[2][1]=y-1; arr[3][0]=x-1; arr[3][1]=y; arr[4][0]=x+1; arr[4][1]=y; arr[5][0]=x-1; arr[5][1]=y+1; arr[6][0]=x; arr[6][1]=y+1; arr[7][0]=x+1; arr[7][1]=y+1; return arr; } for(var i=0;i<500;i++) { var test = getTileNear(i*2,i*2+1); }Si los índices son de 32 bits, esto es un 400 % más rápido:
function initTileNear(){ var out = new Array(8); for(var i=0;i<8;i++) { out[i]=new Uint32Array(2); out[i][0]=0; out[i][1]=0; } return out; } var arr = initTileNear(); function getTileNear(x,y){ arr[0][0]=x-1; arr[0][1]=y-1; arr[1][0]=x; arr[1][1]=y-1; arr[2][0]=x+1; arr[2][1]=y-1; arr[3][0]=x-1; arr[3][1]=y; arr[4][0]=x+1; arr[4][1]=y; arr[5][0]=x-1; arr[5][1]=y+1; arr[6][0]=x; arr[6][1]=y+1; arr[7][0]=x+1; arr[7][1]=y+1; return arr; } for(var i=0;i<500;i++) { var test = getTileNear(i*2,i*2+1); }Si puede usar una sola dimensión, es 10 veces más rápido:
function index(y,x) { return x+y*2; } function initTileNear(){ var out = new Uint32Array(16); for(var j=0;j<8;j++) for(var i=0;i<2;i++) out[index(j,i)]=0; return out; } var arr = initTileNear(); function getTileNear(x,y){ arr[0]=x-1; arr[1]=y-1; arr[2]=x; arr[3]=y-1; arr[4]=x+1; arr[5]=y-1; arr[6]=x-1; arr[7]=y; arr[8]=x+1; arr[9]=y; arr[10]=x-1; arr[11]=y+1; arr[12]=x; arr[13]=y+1; arr[14]=x+1; arr[15]=y+1; return arr; } for(var i=0;i<500;i++) { var test = getTileNear(i*2,i*2+1); }