7

I developed a c# library which used across 3 project that relay in that specific piece of code, though, I still need to use that code in a javascript, so im porting it out, the thing is, I don't think I can replicate the same logic, for example, I've been thinking about this for a few days I couldn't get to the answer.

In the C# library I have a 3D array which is kinda like the core property in the application, and I cannot seem to figure out how to make that work in JS environment.

For example I have this piece of code:

public Obj[,,] objs = new Obj[18, 14, 8];

In which I would allocate objects in EVERY single position, and trying to port that to javascript, seemingly would result in:

var 3dArr = new Array();
    3dArr[0] = new Array();
    3dArr[0][0] = new Array();

Wouldnt this always hold the array object in the first position and if I set whatever else I would lose the whole array? Or am I wrong

2
  • 1
    You are correct. There is no built-in type that represents multidimensional arrays in JS. Commented Sep 5, 2016 at 7:44
  • 1
    You can build it in JS either as nested Arrays, I think this would describe it in C# public Obj[ Obj[ Obj[] ] ] objs, or you create an adapter with an API that takes n-dimensional positions and maps them to one-dimensional keys/indices on an internal data-structure. like key = [x,y,z].join('::') or index = (x*14+y)*8+z. Sure +validation, that the position ain't out of bounds. Commented Sep 5, 2016 at 8:01

4 Answers 4

2

At the time of writing, there is no language feature in JavaScript that would closely resemble multidimensional arrays in C#. It is also not recommended to expose ordinary arrays for the usage of whole application as that would make it easy to mistakenly harm the whole code by writing to the array something it is not supposed to hold.

However, it should be relatively easy to encapsulate an array you need into a simple new class, e.g. Array3d in the code below:

/***** CODE OF THE ARRAY *****/
function Array3d(width, height, depth, type) {
    this.width = width;
    this.height = height;
    this.depth = depth;
    this.type = type;
    this.array = new Array(width * height * depth);
}

Array3d.prototype = {
    get: function(x, y, z) {
        return this.array[calcIndex(this, x, y, z)];
    },
    set: function(x, y, z, item) {
        if (!(item instanceof this.type)) {
            throw new Error(item + ' is not instance of ' + this.type + '.');
        }
        this.array[calcIndex(this, x, y, z)] = item;
    }
};

function calcIndex(array3d, x, y, z) {
    return x + array3d.width * y + array3d.width * array3d.height * z;
}

/***** USAGE CODE *****/
function Something(i) {
    this.index = i;
}

var array3d = new Array3d(10, 11, 12, Something);
var something = new Something(11);
array3d.set(4, 0, 0, something);
var gettingBack = array3d.get(4, 0, 0);
if (gettingBack === something) {
    console.log('1: Works as expected');
}
else {
    console.error('1: Not expected ' + gettingBack);
}
gettingBack = array3d.get(0, 0, 4);
if (gettingBack == null) {
    console.log('2: Works as expected');
}
else {
    console.error('1: Not expected ' + gettingBack);
}

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, I gave it a thought about calculating the object's position based on x, y and z coordinates, just wanted to make sure I was 100% certain it was not possible to achieve it using array[x, y, z]. Your answer seems like the way to go. I'll give it a go and test it out. Thanks!
1

Try this ...

Array3d = function (width, height, depth, defaultValue) {
   width = width || 1;
   height = height || 1;
   depth = depth || 1;
   defaultValue= defaultValue|| 0;
   var arr = [];
   for (var i = 0; i < width; i++) {
      arr.push([]);
      for (var j = 0; j < height; j++) {
         var last = arr[arr.length - 1];
        last.push([]);
        for (var k = 0; k < depth; k++) {
            last[last.length - 1].push(defaultValue);
        }
      }
   }
   return arr;
}
console.log(new Array3d(3, 5, 2, 0));

So, specify the width, height, depth (these three default to 1), and defaultValue (defaults to zero) and you can manipulate it just as you would any javascript array ...

Comments

1

In javascript a 3D array is created as an array of arrays of arrays:

var 3DArr = [[[],[],[]],[[],[],[]],[[],[],[]]];

now 3DArr is an array with arrays inside of it, each of which also contain arrays. So you can do (for example):

3DArr[0][1].push(10);
console.log(3DArr); // [[[],[10],[]],[[],[],[]],[[],[],[]]]

Comments

0

In newer browsers, array of arrays can be initialized with Array.from:

a = Array.from(Array(3), () => Array.from(Array(3), () => Array(3).fill(0)))

console.log(JSON.stringify(a))

As a side note, JavaScript "Array" is more like a special Dictionary that uses its integer keys:

a = []
a['1'] = 2
a.b = 'c'
a[3.14] = Math.PI

console.log(a)                    // "[undefined, 2]"
console.log(a[1], a.b, a['3.14']) // "2 c 3.141592653589793"

so you can assign values to it before initializing all of the "dimensions":

function set(a, x, y, z, v) {
  if(!a[x]) a[x] = []
  if(!a[x][y]) a[x][y] = []
  a[x][y][z] = v
}

a = []
set(a, 1, 2, 3, 4)

console.log(a)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.