【问题标题】:Where/how to set increment on loop and update array only when condition found?仅在找到条件时在哪里/如何设置循环增量和更新数组?
【发布时间】:2019-08-24 14:57:32
【问题描述】:

我正在编写一个函数来遍历 Google Drive 上的文件夹并将文件(Google 表格)与变量字符串(在表格单元格上指定的日期)匹配。当找到匹配的文件时,包含的文件夹名称字符串将分配给 folderItems[0],并将文件 URL 分配给 folderItems[1]。找到文件夹中的所有匹配文件后,以相同的方式迭代下一个文件夹。这些“folderItems”数组存储在父数组“folderItemsContainer”中,以创建一个二维数组,然后可以使用 .setValues() 将其输出到电子表格。

我无法弄清楚如何或在何处放置增量变量,以便它仅在文件名匹配时递增,但在未找到匹配时不会停止循环。

我尝试了各种结构,包括互换 for 和 while 循环以及在看似有用的地方插入 if 语句。我在 Stackoverflow 上查看了一些不同的答案,这些答案几乎是有意义的,但似乎都不适用于这里。我对编程相当陌生。我已经尝试过不同的代码变体,但这是我目前为止的目标:

function GetFolderData() {
  var currentSheet = SpreadsheetApp.getActiveSpreadsheet();
  var currentYearPeriod = currentSheet.getRange("C1!A4").getValue();
  // Logger.log(currentYearPeriod);

  //Get folder objects from parent folder
  var parentFolderId = "17F0fcBH0jmxsk2sUq723AuIY0E2G_u0m";
  var parentFolder = DriveApp.getFolderById(parentFolderId);

  //Get folders from specified parent folder
  var StaffFolders = parentFolder.getFolders();

  //Create container array
  var folderItemsContainer = [];
  //Create Item Array
  var folderItems = [];
  var i = 0;

  //For every staff folder, regardless of content, do:
  while (StaffFolders.hasNext()) {
    //Get current folder object
    currentFolder = StaffFolders.next();

    //Get files in current folder object as FileIterator
    FolderFiles = currentFolder.getFiles();

    //If folder empty, outer while loop will iterate
    if (FolderFiles !== null) {
      //Iterate through existing files
      while (FolderFiles.hasNext()) {
        //Get file object sequentially
        file = FolderFiles.next();

        //When filename matches currentYearPeriod, store URL next to name in folderItems
        for (i = 0; file.getName().indexOf(currentYearPeriod) !== -1; i++) {
          folderItems[i] = [];

          folderItems[i][0] = currentFolder.getName();
          //  Logger.log(currentFolder.getName());

          folderItems[i][1] = file.getUrl();

          folderItemsContainer[i] = folderItems[i];
        }
      }
    }
  }

  return folderItemsContainer;
}

function InsertFolderData() {
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange("B4:Z1000").clearContent();
  FolderData = GetFolderData();
  Logger.log(FolderData);
  sheet
    .getRange(4, 2, FolderData.length, FolderData[0].length)
    .setValues(FolderData);
  Logger.log(FolderData);

  /* var str = "";

  for (var i = 0; i < FolderData.length; i++) {
    str += FolderData[i] + "\r\n";
  }
  str = str.substr(0);

  var ui = SpreadsheetApp.getUi();
  ui.alert("DATA IMPORTED: " + "\r\n" + str);

  */
}

使用上面的代码,我不完全确定为什么,但我似乎陷入了无限循环并且脚本没有完成。我希望实现的是 folderItemsContainer 数组填充了包含与 currentYearPeriod 变量匹配的文件的文件信息(父文件夹名称 [0] 和文件 URL [1])的数组。我一直在重构代码,学到了很多东西,但不幸的是没有解决问题。

【问题讨论】:

    标签: javascript arrays google-apps-script


    【解决方案1】:

    您应该检查每个循环之间的区别是什么,您并没有完全消除它们。如果要执行 for 循环内的指令直到满足某个条件,在这种情况下为file.getName().indexOf(currentYearPeriod) !== -1,则应使用 while 循环。错误是之前的条件永远不会满足,因为file 在运行for 循环时永远不会改变。这就是为什么你有一个无限循环。我的解决方案:

    // new variable
    var cnt = 0;
    
    while (StaffFolders.hasNext()) {
        currentFolder = StaffFolders.next();
        FolderFiles = currentFolder.getFiles();
    
        if (FolderFiles !== null) {
          while (FolderFiles.hasNext()) {
            file = FolderFiles.next();
    
            // You for loop started here
            folderItems[cnt] = [];
            folderItems[cnt][0] = currentFolder.getName();
            folderItems[cnt][1] = file.getUrl();
            folderItemsContainer[cnt] = folderItems[cnt];
    
            // each time you read a new file you increment by 1
            cnt++;
          }
        }
        // this reset the counter for each new folder
        cnt = 0;
      }
    

    循环之间的差异:

    for 循环

    当您知道需要多少次迭代时使用它们。例如,如果你想在控制台打印一个字符串的所有字符:

    const str = "hello";
    for(let i = 0; i < str.length; i++) {
       console.log(str.charAt(i));
    }
    
    • let i = 0是起点
    • i &lt; str.length 是你想停下来的时候。如果您必须使用不是以下&lt;, &lt;=, &gt;, &gt;= 之一的符号,则不应使用for 循环。
    • i++ 你想如何到达停靠点。

    while 循环

    如果你不知道你的循环什么时候结束,如果有,5 次迭代,100 次迭代或 0 次迭代。你应该使用while 循环。

    function getFirstL(str)
       let i = 0;
       while(i < str.length && str.charAt(i) !== "l"){
          i++;
       }
    }
    

    【讨论】:

    • 非常感谢您对此进行解释并提供示例代码。为了我的目的,我需要对其进行一些调整,但我已经学到了关于 while 循环和递增的课程,这帮助我弄清楚了。我会在这里发布工作代码以帮助其他人,但字符限制不允许这样做。再次感谢。
    • 很高兴它对您有所帮助。
    【解决方案2】:

    你的 for 循环。这是for循环的语法。

    for (statement 1; statement 2; statement 3) {
      // code block to be executed
    }
    

    语句 1 在代码块执行之前执行(一次)。

    语句2定义了执行代码块的条件。

    在代码块执行后(每次)执行语句 3。

    您的 for 循环没有定义退出条件。最小值或最大值。像

    i<file.getName().indexOf(currentYearPeriod); 
    

    所以它会检查从 0 到那个值。

    【讨论】:

      猜你喜欢
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 1970-01-01
      • 2020-02-09
      相关资源
      最近更新 更多