How to add/append data to multidimensional array in google script

Viewed 1568

Is it possible to add to a multidimensional array of unknown size without using a google sheets(spreadsheet) to hold the data? Looking everywhere and can't find an example for a 3 dimensional array.

Here is what I want to do:

var aDirTree=[];    
aDirTree[0][0][0]="myName1";
aDirTree[0][0][1]="myURL1";
aDirTree[1][0][0]="myName2";
aDirTree[1][0][1]="myURL2";
//Notice we are skipping elements
aDirTree[2][5][0]="myName3";
aDirTree[2][5][1]="myURL3";

Where values that are skipped are null? I'm guessing it might be some sort of push method.

2 Answers

In the lazier version, array can be used as a key (but it's converted to string) :

var o = {}
o[[1,2,3]]='a'
o['4,5,6']='b'

console.log(o)           // { "1,2,3": "a", "4,5,6": "b" }
console.log(o[[0,0,0]])  // undefined

Proxy(not available in IE) can be another alternative, but it will create a lot of extra values:

var handler = { get: (a, i) => i in a ? a[i] : a[i] = new Proxy([], handler) }

var a = new Proxy([], handler)

a[1][2][3]='a'
a[4][5][6]='b'

console.log(a)           // [[],[[],[],[[],[],[],"a"]],[],[],[[],[],[],[],[],[[],[],[],[],[],[],"b"]]]
console.log(a[0][0][0])  // []

And finally, the "real" answer:

function set(a, x, y, z, v) { ((a = a[x] || (a[x] = []))[y] || (a[y] = []))[z] = v }
function get(a, x, y, z, v) { return (a = a[x]) && (a = a[y]) && z in a ? a[z] : v }

var a = []
set(a,1,2,3,'a')
set(a,4,5,6,'b')

console.log( get(a,0,0,0) )            // undefined
console.log( get(a,0,0,0,'default') )  // "default"
console.log( a )                       // [,[,,[,,,"a"]],,,[,,,,,[,,,,,,"b"]]]


Bonus: combination of all 3, but not very efficient, because the keys are converted to strings:

var a = [], p = new Proxy(a, { set: (a, k, v) => 
  ([x,y,z] = k.split(','), ((a = a[x] || (a[x] = []))[y] || (a[y] = []))[z] = v) })

p[[1,2,3]] = 'a'
p[[4,5,6]] = 'b'

console.log( a[[0,0,0]] )  // undefined
console.log( a )           // [,[,,[,,,"a"]],,,[,,,,,[,,,,,,"b"]]]

function writeToTree(tree, first, second, third, value)
{
    tree[first]                || (tree[first]                = []);
    tree[first][second]        || (tree[first][second]        = []);
    tree[first][second][third] || (tree[first][second][third] = []);

    tree[first][second][third] = value;
}
var aDirTree = [];
writeToTree(aDirTree, 1, 55, 3, "someValue");

Or recursively, giving you arbitrary depth:

function writeToTree(tree, position, value)
{
    var insertAt = position.shift();
    tree[insertAt] || (tree[insertAt] = []);
    if (position.length === 0)
    {
        tree[insertAt] = value;
        return;
    }
    writeToTree(tree[insertAt], position, value);
}
var aDirTree = [];
writeToTree(aDirTree, [1, 55, 3], "someValue");
console.log(aDirTree);
Related