【问题标题】:How to add/append data to multidimensional array in google script如何在谷歌脚本中添加/追加数据到多维数组
【发布时间】:2017-11-22 23:55:30
【问题描述】:

是否可以在不使用谷歌表格(电子表格)保存数据的情况下添加到未知大小的多维数组?到处找,找不到 3 维数组的例子。

这是我想做的:

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

哪些被跳过的值为空?我猜这可能是某种推送方法。

【问题讨论】:

    标签: javascript arrays multidimensional-array


    【解决方案1】:

    在惰性版本中,数组可以用作键(但它被转换为字符串):

    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) 可以是另一种选择,但它会创造很多额外的价值:

    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])  // []

    最后,“真正”的答案:

    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:所有 3 的组合,但效率不高,因为键被转换为字符串:

    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"]]]

    【讨论】:

    • 天哪,我喜欢运行代码片段功能。您能否修改该代码以读取输入到数组中的值。我看到了日志输出,但是当我尝试读取值 o[0][0][0] 时出现错误。
    • 对荒谬的Proxy 解决方案投赞成票;)
    • 啊,我试图错误地访问字符串。我让您的第一个示例起作用.. 我必须引用我想要提取的元素,例如 aDirTree[[0,0,0]] 我将不得不花一点时间来看看您的第二个示例中发生了什么。谢谢。
    【解决方案2】:
    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");
    

    或者递归,给你任意深度:

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

    【讨论】:

    • 太好了。你为它创建了一个函数。我将不得不弄清楚你的意思是用任意深度递归并测试它。我还注意到您上面的一个答案似乎简短而简单,但它还不起作用,或者我执行错误。
    • @Slai 的答案没有返回array,而是返回object,这可能会导致您正在使用的库出错。 “任意深度”是指您可以使用该函数创建 4-、5-、6- ... 维数组。
    • 太棒了,我现在明白了。我用 4 维数组测试了它。我认为您有一个错字,因为我必须更改递归数组代码行以读取 writeToTree(tree[insertAt], position, value) 而不是引号中的“someValue”。
    • 是的,在移动设备上编写代码很难......已修复,谢谢!
    • 作为记录,他的方法似乎很短,但不确定如何使用我上面的示例将返回的对象转换为字符串值。也许他会有一点时间来澄清这一点。在您的第一个非递归方法中,双管道的作用是什么。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 2020-06-02
    • 2021-10-05
    • 1970-01-01
    • 2012-01-16
    • 2014-08-25
    • 2019-06-27
    相关资源
    最近更新 更多