【问题标题】:Google Apps Script - ForEach in RangeGoogle Apps 脚本 - 范围内的 ForEach
【发布时间】:2016-09-02 17:41:34
【问题描述】:

对于一个范围内的每一行,我想在一个数组中添加一个或多个条目,具体取决于 int 的值,在该行的一个列中。 例如,如果我的行是:

Val1   1

我想将一个对象 {Val1,'US'} 推送到我的数组中。 另一方面,如果我的行是:

Val1   2

我想将两个对象:{Val1,'FR'}, {Val1,'DE'} 推送到我的数组中。 我无法弄清楚为什么以下代码不起作用:

  var range = sheet.getRange("A2:B");
  var results = range.getDisplayValues();
  var array = [];

  results.forEach(function(row){          

    switch(row[1]){
      case '1' :               
        row[1] = "US";        
        array.push(row);                        
        break;
      case '2' :
        row[1] = "FR";
        array.push(row);      
        row[1] = "DE";
        array.push(row);     
        break; 
      case '3' :
        var entry1 = row;
        var entry2 = row;
        entry1[1] = "UK";
        entry2[1] = "SW";
        array.push(entry1);      
        array.push(entry2);      
        break;            
    }           
  });    
return array;

这会返回两次“DE”和两次“SW”。我在案例三中尝试了不同的方法,以确保问题不在于变量引用,但同样的事情也会发生。可能是因为我循环价值的方式吗?为什么会这样?

感谢您的帮助。

【问题讨论】:

  • 您可以为输入/输出添加示例值吗?目前还不是很清楚你期望你的输出是什么

标签: javascript foreach google-apps-script


【解决方案1】:

您正在就地修改“行”,而没有制作副本。即,您将对“行”(同一个数组)的引用放入多个位置,然后再次修改“行” - 从而覆盖您的原始更改。

为避免此问题,您可以使用 Array.slice() 来复制行,如下所示:

var range = sheet.getRange("A2:B");
var results = range.getDisplayValues();
var array = [];

results.forEach(function(row) {
  switch(row[1]) {
    case '1' :
      // No copy necessary, since you're only using it once              
      row[1] = "US";
      array.push(row);
      break;
    case '2' :
      // Copy not necessary for the first use
      row[1] = "FR";
      array.push(row);
      // Copy here, since you will modify it again
      row = row.slice();
      row[1] = "DE";
      array.push(row);
      break; 
    case '3' :
      // Make one extra copy
      var entry1 = row;
      var entry2 = row.slice();
      entry1[1] = "UK";
      entry2[1] = "SW";
      array.push(entry1);
      array.push(entry2);
      break;
  }
});
return array;

请注意,对于您推送的数组中只有两个元素的情况,为每种情况构建新数组(如另一个答案所示)可能会更好。而且,如果我要在性能不是很关键的生产代码中使用它,我可能会为每个修改制作一个副本,而不是上面的 just-when-you-need-it 变体。我在上面编写它的方式演示了 必要的 副本(以便更容易理解这一点),但与只是防御性地复制所有内容相比,通过更改使其不正确要容易得多。

【讨论】:

    【解决方案2】:

    这是因为JS推送了一个变量然后修改,所以值到处都被替换了。

    尝试像这样直接推送,不存储:

      var range = sheet.getRange("A2:B");
      var results = range.getDisplayValues();
      var array = [];
    
      results.forEach(function(row){          
    
        switch(row[1]){
          case '1' :               
            array.push([row[0],"US"]);                        
            break;
          case '2' :
            array.push([row[0],"FR"]);      
            array.push([row[0],"DE"]);     
            break; 
          case '3' :
            array.push([row[0],"UK"]);      
            array.push([row[0],"SW"]);      
            break;            
        }           
      });    
    return array;
    

    【讨论】:

    • 所以这意味着当你将一个变量推送到一个数组时,该变量仍然在范围内?啊啊Js...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 2014-10-05
    相关资源
    最近更新 更多