Creating hash array in Google Apps Script

后端 未结 3 443
再見小時候
再見小時候 2021-02-04 22:26

I\'ve been trying to work with Trello and the Google Apps Script this week. I am trying to create an array of hashes that I can then use to load the spreadsheet. Google apps s

相关标签:
3条回答
  • 2021-02-04 22:57

    Summary: For onEdit() purposes, use Cache Service to define associative array data.

    Here's a shared Gsheet demonstrating this curious behavior. I tried the following solution in programmatically defining an associative array based on data in a Google sheet.

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

    To execute this, you run the init() method in the onOpen() event handler.

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

    The logger message confirms that init() loads the data from the worksheet.

    Now if I try to reference this assocArr object in onEdit() it returns undefined for all key values.

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

    I infer that for security reasons, Google limited the simple-trigger onEdit() to not have global variable scope, same as they voided the utility of the event.user property.

    Now instead if I simply put the key-value pair in the cache, it works! Here is the complete code that works using the Cache Service.

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

    Curiously, the onEdit() has the cache variable in its scope.

    Here again is the shared Gsheet demonstrating this curious behavior.

    0 讨论(0)
  • 2021-02-04 22:58

    I know this is an old post / question, but i would like to update my answer since the original anwer (1st answer) is misleading. I was myself looking for how to return associative arrays back to a cell in the spreadsheet, but alas.. "YOU CANNOT". Google spreadsheet MUST want an numerically indexed array or an object. Otherwise it returns "#ERROR".

    Here are the steps to replicate the issue.

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

    Solution (rather a workaround)

    1: Transfer your objects from your associative array into a numerically indexed array using for-each type loop.

    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. 
    }
    

    If you used a temp like numerically indexed array, you can return "temp" back to the calling cell.

    0 讨论(0)
  • 2021-02-04 23:00

    Reading the question, I understood that the author needs to know how to create an associative array in a GAS. If it is correct then here is a couple of links (here and here) and a sample code is bellow.

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

    If the author needs really

    an array of hashes

    then there are a couple of ways depending on which hash algorithm is required.

    1. to use the Utilities.computeDigest method to calculate a hash of a string using one of available algorithms.
    2. if the required hash calculation algorithm is not supported by the Utilities.computeDigest, then is possible to write own implementation as it is done for the BLAKE function.

    Here is a sample of how to create an array of hashes using the MD5 hash.

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

    P.S. The return line of the author code return name, label; //return list for output is not correct - only the label variable value is returned. To return a couple of variables as an array is necessary to write return [name, label];. Or may be the author needs to return the list variable and not name and label.

    0 讨论(0)
提交回复
热议问题