-1

i am attempting to get all of the indexes near a certain index in a 2d array. i currently have:

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;
}

I do not care about indexes that are out of the array, i just want a more efficient way to do this.

minswepe
  • 1
  • 1
  • What do you mean by "more efficient"? Less code? Not using _.push(...)_? Something else? As it stands it's quite difficult to answer your question. – chazsolo Jun 01 '22 at 00:22
  • i mean less code, i have this problem very frequently, and would appreciate a different solution. the code being more efficient in terms of performance would be more of a plus, but still a priority. i am not well versed with javascript. – minswepe Jun 01 '22 at 01:49

2 Answers2

1
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;
}

Using for loops...

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;
}
danh
  • 62,181
  • 10
  • 95
  • 136
0

If the output is intended to be used in serial algorithm (not needing a different array for each call), then by not creating a new array every time, you can compute it faster:

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);

}

this is 300% faster than the original version that re-creates new array everytime.

With a bit longer code, it gets faster:

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);

}

If indices are 32-bit, then this is 400% faster:

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);

}

If you can use single-dimension, it is 10x faster:

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);

}
huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97