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