【问题标题】:Why do the arrays in my google apps script get overwritten?为什么我的谷歌应用脚​​本中的数组会被覆盖?
【发布时间】:2020-02-21 21:57:29
【问题描述】:

我有一个大数组,其中包含来自电子表格的所有数据,我从中派生包含初始数组部分的较小数组。

现在,随着每一步,前一个数组都会发生变化并变得等于派生数组,直到最后所有数组都相同。

知道我做错了什么吗?

(我不是专业人士,仍在构建脚本的过程中,所以请多多包涵:丑陋/低效的代码:)

function dataTables() {


  /* All spreadsheet data to tables */


  var mastersheet = SpreadsheetApp.openById("xyz");


  // Data array of whole sheet with values in "Artikelbezeichnung" (field 6)
  var completeTable = mastersheet.getSheetByName("Mastersheet").getDataRange().getValues();
  completeTable.splice(0,2); // Remove header lines 1 & 2
  for ( i = completeTable.length; i > 0 ; i-- ) {
    if (completeTable[i-1][6-1] == "") { completeTable.splice(i-1,1); } // Remove lines with empty "Artikelbezeichnung" (field 6) if necessary
  }

  Logger.log(completeTable); // Log 1

  // Indexeded data array of whole sheet
  var completeTableIndexed = completeTable;
  for ( i = completeTableIndexed.length; i > 0; i-- ) {
    completeTableIndexed[i-1].unshift(i+2);
  }

  Logger.log(completeTableIndexed); // Log 2
  Logger.log(completeTable);

  // Data array of all lines eligible for RTN sheet with Indexed
  var rtnTableIndexed = completeTableIndexed;
  for ( i = rtnTableIndexed.length; i > 0 ; i-- ) {
    if ( rtnTableIndexed[i-1][17] == "Nein" ) { rtnTableIndexed.splice(i-1,1); } // Remove lines with "Reparaturcontroller" (field 17) = "Nein"  if necessary
    else if ( rtnTableIndexed[i-1][28] != "" ) { rtnTableIndexed.splice(i-1,1); } // Remove lines with "Versanddatum G4G -> Hersteller" (tracker, field 28) if necessary
    else if ( rtnTableIndexed[i-1][23] == "Ja" && rtnTableIndexed[i-1][25] == "" ) { rtnTableIndexed.splice(i-1,1); } // Remove lines with "KVA (J/N)" (field 23) = "Ja" and KVA is not yet confirmed ("KVA bestätigt am", field 25) if necessary
  }


  // Data array of all lines eligible for KVA sendings with Indexed
  var kvaTableIndexed = completeTableIndexed;
  for ( i = kvaTableIndexed.length; i > 0 ; i-- ) {
    if ( kvaTableIndexed[i-1][23] != "Ja" && kvaTableIndexed[i-1][24] != "" ) { kvaTableIndexed.splice(i-1,1); } // Remove lines with "KVA (J/N)" (field 23) not "Ja" and "KVA versendet am" (field 24) not empty if necessary
  }


  var results = [completeTableIndexed,rtnTableIndexed, kvaTableIndexed, completeTable]; // Log 3

  Logger.log(completeTableIndexed); // Log 4
  Logger.log(rtnTableIndexed);
  Logger.log(kvaTableIndexed);
  Logger.log(completeTable);




}

日志 1 的预期输出是完整的电子表格数据,没有一些空行 - 工作正常,输出大约 15 行。

Log 2 的预期输出是第一步的索引数组以及原始数组。相反,它会输出索引数组两次。

Log 3 和 4 的预期输出将是原始数组、索引原始数组和两个分解的数组,每个数组大约两行。相反,所有记录的数组都是包含两行的分解数组。它们都是相同的。

在此过程中,原始完整数组似乎被多次覆盖。

【问题讨论】:

  • 在发布任何其他问题之前,我建议您借此机会参加tour 并学习如何How to Ask 以及如何编写minimal reproducible example。因为你的问题很广泛,而且你的例子很复杂。
  • 好的,谢谢你的好意。我会的!
  • 正如我在下面的评论中所说,你的问题挑战了我认为我对 slice 的所有了解,所以我觉得有必要在 Stack Overflow 上问一个问题,但是当我写这个问题时,我问自己这个问题想知道它是否仅适用于一维数组。就像过去很多次一样,当我试图写一个最小的综合问题时,它引导我找到了解决方案。因此根本不需要问这个问题。
  • 我明白,有道理!

标签: javascript arrays logging google-apps-script


【解决方案1】:

而不是使用这个var completeTableIndexed = completeTable;

试试这个:

var completeTableIndexed=[];
completeTable.forEach(function(r){completeTableIndexed.push(r.slice();});

这将返回整个数组的副本,而不是对它的引用。在研究这个时,我发现 slice 似乎不适用于多维数组。我不知道这是否会解决您的所有问题,因为您的问题非常广泛。但这可能会帮助您走得更远。

【讨论】:

  • 非常感谢,您的解决方案效果很好。实际上,在处理数组时它会创建引用而不是副本是问题所在。这个 Stackoverflow 线程给出了关于存在哪些克隆数组的方法以及哪些方法最快的全面答案,尽管并非所有这些方法似乎都适用于应用程序脚本:Fastest way to duplicate an array in JavaScript
  • 感谢您提供的链接,我想了解更多相关信息。我承认我发现解决你的问题很有挑战性,因为我认为 slice() 可以在二维数组上工作,但我无法让它工作。我不得不将它们分解成扁平的阵列。有一段时间,它挑战了我对这个 slice() 的了解。
  • 我很高兴我能回馈一些东西。据我了解这篇文章,您的解决方案甚至是处理数组复制的最快/最佳方式。干得好,再次感谢!
猜你喜欢
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 2021-10-29
  • 2018-03-29
  • 1970-01-01
  • 2020-12-31
  • 2011-09-22
  • 1970-01-01
相关资源
最近更新 更多