【问题标题】:Creating hash array in Google Apps Script在 Google Apps 脚本中创建哈希数组
【发布时间】:2012-09-20 23:22:20
【问题描述】:

这周我一直在尝试使用 Trello 和 Google Apps 脚本。我正在尝试创建一个哈希数组,然后我可以使用它来加载电子表格。 Google 应用程序脚本不喜欢创建散列的典型 javascript 代码。我查看了文档,但他们没有像哈希这样的东西......他们说:

 var object = [];
 var object1 = {};
 object.push(object1);

这行不通,因为我实际上是在尝试做类似的事情:

var hash={name: , label: };
var n= someNumber;
var l= someLabel
var hash.push(name: n, label: l);

基本上这就是我现在拥有的代码。但这是我的全部功能:

  function getData(){
  var list={};
  //get the list of delivered cards from Trello
  var listRequest = authorizeToTrello(); // get authorization
  var result = UrlFetchApp.fetch("https://trello.com/1/lists/4fea3a2c3a7038911ebff2d8/cards",
  listRequest);//fetch list
  var listOfCards = Utilities.jsonParse(result.getContentText());//Google app utility format json

  //outer loop to iterate through list of Cards
  for(var i=0; i < listOfCards.length; i++){
     var cardId = listOfCards[i].id; //get the id of a single card
     var l = listOfCards[i]["label"]; //get the label for the our structure

  //get a json object for a single card within the list of cards iteration 
  var cardRequest = authorizeToTrello();
  var getCard = UrlFetchApp.fetch("https://trello.com/1/cards/" + cardId + "/actions", cardRequest); 
  var singleCard = Utilities.jsonParse(getCard.getContentText());

 //inner loop to iterate the single cards JSON objects

  for(var j=0; j < singleCard.length; j++) {
    if(singleCard[j].data != undefined && singleCard[j].data.listAfter != undefined)
    {
      var str = singleCard[j]["data"]["listAfter"]['name'];
      if(str === "Delivered Q3 2012"){
          var n = singleCard[j]['memberCreator']['fullName'];
        }
     }
  }
    //push the data to list
    list.push(n,l);
  }

 return name, label; //return list for output
 }

【问题讨论】:

    标签: javascript arrays hash google-apps-script trello


    【解决方案1】:

    阅读问题后,我了解到作者需要知道如何在 GAS 中创建 an associative array。如果正确,那么这里有几个链接(herehere),下面是示例代码。

    function testMap() {
      var map = {};
      map["name1"] = "value1";
      map["name2"] = "value2";
      return map;
    }
    

    如果作者真的需要

    哈希数组

    然后有几种方法,具体取决于所需的哈希算法。

    1. 使用Utilities.computeDigest 方法使用available algorithms 之一计算字符串的哈希值。
    2. 如果Utilities.computeDigest不支持所需的哈希计算算法,则可以编写自己的实现,因为donedone

    这里是如何使用 MD5 哈希创建哈希数组的示例。

    function testHash() {
      var array = [];
      array.push(Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, "value1"));
      array.push(Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, "value2"));
      return array;
    }
    

    附:作者代码return name, label; //return list for output 的返回行不正确——只返回label变量值。要将几个变量作为数组返回,需要编写return [name, label];。或者可能是作者需要返回list 变量而不是namelabel

    【讨论】:

      【解决方案2】:

      我知道这是一个旧帖子/问题,但我想更新我的答案,因为原始答案(第一个答案)具有误导性。我自己在寻找如何将关联数组返回到电子表格中的单元格,但是唉......“你不能”。 Google 电子表格必须需要一个数字索引数组或对象。否则返回“#ERROR”。

      以下是复制问题的步骤。

      function testMap() {
        var map = {};
        map["name1"] = "value1";
        map["name2"] = "value2";
        return map
      
      Formula in your cell: =testMap()
      Value in your cell: Thinking... #ERROR
      

      解决方案(相当一种解决方法)

      1:使用 for-each 类型循环将对象从关联数组转移到数字索引数组中。

      var temp = new Array();
      for (var i in map) {
          temp.push([i,map[i]])
          // optionally use activeSheet.getRange(X:X).setValue([i,map[i]])) function here.
         // set values will not work in cell functions. To use it via cell functions, rerun / trigger the functions using an on_edit event. 
      }
      

      如果您使用了类似数字索引数组的 temp,则可以将“temp”返回给调用单元格。

      【讨论】:

        【解决方案3】:

        总结:对于onEdit()的目的,使用缓存服务来定义关联数组数据。

        这是a shared Gsheet 展示了这种奇怪的行为。我尝试了以下解决方案,以编程方式根据 Google 表格中的数据定义关联数组。

        var assocArr = {
          labels: {},
          init: function () {
            var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetName');
            var values = sheet.getDataRange().getValues();
            for(var row in values) {
              assocArr.labels[values[row][0]] = values[row][1];
            };
            for(var key in assocArr.labels) {
              Logger.log("key: %s, value: %s",key, assocArr.labels[key]);
            };
            return(void(0));
          },
        };
        

        要执行此操作,请在 onOpen() 事件处理程序中运行 init() 方法。

        function onOpen() {
          assocArr.init();
          var key = 'test';
          SpreadsheetApp.getUi().alert( assocArr.labels[key] );
          Logger.log("onOpen: key: %s, value: %s",key, assocArr.labels[key]);
        };
        

        记录器消息确认init() 从工作表加载数据。

        现在,如果我尝试在 onEdit() 中引用这个 assocArr 对象,它会为所有键值返回 undefined

        function onEdit(event) {
          var key = 'test';
          SpreadsheetApp.getUi().alert( assocArr.labels[key] );
          Logger.log("onEdit: key: %s, value: %s",key, assocArr.labels[key]);
        };
        

        我推断出于安全原因,Google 将简单触发器 onEdit() 限制为不具有全局变量范围,就像他们取消了 event.user 属性的实用程序一样。

        现在,如果我只是将键值对放入缓存中,它就可以工作!这是使用缓存服务的完整代码。

        var cache = CacheService.getPrivateCache();
        
        var assocArr = {
          init: function () {
            var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Account Labels');
            var values = sheet.getDataRange().getValues();
            for(var row in values) {
              cache.put(values[row][0], values[row][1], 3600);
            };
            return(void(0));
          },
        };
        
        function onOpen() {
          assocArr.init();
          var key = 'test';
          SpreadsheetApp.getUi().alert( cache.get(key) );
          Logger.log("onOpen: key: %s, value: %s",key, cache.get(key));
        };
        
        
        function onEdit(event) {
          var key = 'test';
          SpreadsheetApp.getUi().alert( cache.get(key) );
          Logger.log("onEdit: key: %s, value: %s",key, cache.get(key));
        };
        

        奇怪的是,onEdit() 在其作用域中有 cache 变量。

        the shared Gsheet 再次展示了这种奇怪的行为。

        【讨论】:

        • “我推断出于安全原因,Google 将简单触发器 onEdit() 限制为没有全局变量范围” - 我认为这是一个不正确的解释。 GAS 脚本在触发(onOpen、onEdit 等)时在服务器上从头开始执行,这意味着您定义的任何变量的生命周期都只有一个服务器执行(即只有一个触发器)。这就是为什么变量“assocArr”(或者就此而言,您声明的任何全局变量)在触发器中不可用的原因。此外,缓存只有从 CacheService 获取(由 GAS 服务器提供)才可用
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-23
        • 2019-06-23
        • 2011-04-20
        • 2014-11-26
        相关资源
        最近更新 更多