0

I need to populate a 3D array automatically, using natural positive numbers (0,1,2,3,4...), up to the array's full dimension. In this case, a 5x3x2 array stores 30 elements. Is there any algorithm, where for-loops could be employed to dynamically populate such array? For example: if I had a 5x3 2D array, I certainly could use the following code, to automatically generate its elements:

var ray = new Array(5);
for (var make2D = 0; make2D < ray.length; make2D++) {
    ray[make2D] = new Array(3);
}
for (var i = 0; i < array.length; i++) {
    for (var j = 0; j < array[i].length; j++) {
        array[i][j] = i * array[i].length + j;
    }
}

The above code would first create a 5 x 3 array and populate this 2D array with elements from 0 to 14. But, I have struggled to find a 'formula' to populate a 3D array likewise

Like explicit: array[ i ] [ j ] [ z ]= '.....code.....' using length property values and for-loops?

Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
  • Take a look at this link. https://stackoverflow.com/questions/4943633/creating-and-parsing-a-3d-array-in-javascript#4943881 – sridhar Nov 13 '17 at 13:02
  • This isn't a question about iterating over an 3d / 2d arrays with hard-coding the elements, basically is filling it up dynamically with natural numbers each of its indexes...like the algorithm explained to fill a 2D array. Thank you for pointing the articles. –  Nov 13 '17 at 13:15

3 Answers3

1

This is a recursive function that accepts an array that describes an n dimensions array, and populates it with consecutive numbers:

function makeNDArray(dims) {
  var counter = 0;
  
  function generateArr(dims) {
    var arr = [];
    var nextDims = dims.slice(1);
    var hasNext = nextDims.length > 0;
    
    for(var i = 0; i < dims[0]; i++) {
      arr.push(hasNext ? generateArr(nextDims) : counter++);
    }
    
    return arr;
  }
  
  return generateArr(dims);
}

var result = makeNDArray([3, 5, 2]);

console.log(result);

And an ES6 version using Array#from to generate the arrays:

function makeNDArray(dims) {
  let counter = 0;
  
  const generateArr = (dims) => {
    const nextDims = dims.slice(1);
    const populate = nextDims.length > 0 ? () => generateArr(nextDims) : () => counter++;
    
    return Array.from({ length: dims[0] }, populate);
  }
  
  return generateArr(dims);
}

const result = makeNDArray([3, 5, 2]);

console.log(result);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

To populate your array you can use the folowing:

let x = 1

for (let i = 0; i < myArray.length; i++){
  for (let j = 0; j < myArray[i].length; j++){
    for (let k = 0; k < myArray[i][j].length; k++){
      array[i][j][k] = x++ ;
    }
  }
}
inetphantom
  • 2,498
  • 4
  • 38
  • 61
  • Thank you 'inetphantom', that was perfect for me. –  Nov 13 '17 at 13:48
  • Hi @Wnog, SO is a portal to share knowledge. To do so, there are mechanisms to tell what is good and what not. Instead of writing a comment saying `Thank You!` we upvote and accept questions. Have a look at the [tour] to learn more about it! – inetphantom Nov 14 '17 at 08:29
  • Indeed, I did up vote. But, as my status indicates 'student', the site engine doesn't count, add up and looks like it doesn't even appear. This is the reason I made sure I wrote a message out of politeness, did not have other resource. –  Nov 14 '17 at 10:41
0

If any of the dimensions are fixed, it's faster to hard code them:

for (var a = [], n = 0, i = 0, j, k; i < 5; i++)
  for (j = 0, a[i] = []; j < 3; j++)
    for (k = 0, a[i][j] = []; k < 2; k++)
      a[i][j][k] = n++                     

console.log(JSON.stringify(a))

// faster
for (var a = [], n = 0, i = 0, j; i < 5; i++)
  for (j = 0, a[i] = []; j < 3; j++)
      a[i][j] = [n++, n++]

console.log(JSON.stringify(a))

// even faster
for (var a = [], i = 0, n = 0; i < 5; i++)
    a[i] = [[n++, n++], [n++, n++], [n++, n++]]

console.log(JSON.stringify(a))

// fastest
var a = [[[0,1],[2,3],[4,5]],[[6,7],[8,9],[10,11]],[[12,13],[14,15],[16,17]],[[18,19],[20,21],[22,23]],[[24,25],[26,27],[28,29]]]

Otherwise, there are many shorter and slower ES6 alternatives (don't work in IE):

// nested:
var n = 0, a = [...Array(5)].map(v => [...Array(3)].map(v => [...Array(2)].map(v => n++)))
console.log(JSON.stringify(a))

var n = 0, r = c => [...Array(c)], a = r(5).map(v => r(3).map(v => r(2).map(v => n++)))
console.log(JSON.stringify(a))

var n = 0, r = (c, f) => [...Array(c)].map(f), a = r(5, v => r(3, v => r(2, v => n++)))
console.log(JSON.stringify(a))

// recursive:
var n = 0, r = (c, ...a) => [...Array(c)].map(v => a[0] ? r(...a) : n++), a = r(5, 3, 2)
console.log(JSON.stringify(a))

var n = 0, r = a => [...Array(a[0])].map(v => a[1] ? r(a.slice(1)) : n++), a = r([5, 3, 2])
console.log(JSON.stringify(a))

// recursive without having to declare n outside of the function:
var r = (a, n = [0]) => [...Array(a[0])].map(v => a[1] ? r(a.slice(1), n) : n[0]++), a = r([5, 3, 2])
console.log(JSON.stringify(a))
Slai
  • 22,144
  • 5
  • 45
  • 53