Home > Software engineering >  Is there a way to do this in javascript easier?
Is there a way to do this in javascript easier?

Time:06-01

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.

CodePudding user response:

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

CodePudding user response:

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

}

CodePudding user response:

Basically you want a cartesian product of two arrays [x, x-1, x 1] and [y, y-1, y 1] Check this question Cartesian product of multiple arrays in JavaScript

  • Related