簡體   English   中英

優化 Google Apps 腳本中的 for 循環函數(可能是數組)?

[英]Optimize for-loop function in Google Apps Script (Arrays maybe)?

第一次海報在這里。 我想了解一些我認為可以改進的 Google App Script 代碼。

長話短說。

我有 2 個 Google Sheet 表格

  • “LOCALE”電子表格- 列出位置的唯一名稱

  • “FEED”電子表格- 列出照片描述,包括位置。 同一位置在此電子表格中多次列出。

  • 這兩個表都有一個“ Location ”列,它通過一個Key列相互引用。

我想解決的問題:

當我在“LOCALE”電子表格中編輯位置名稱時,它應該自動更新“FEED”電子表格中的所有位置名稱。

我解決這個問題的方法是:

為此,我在 for 循環中使用了 for 循環。 總結一下:

  • 對於“ LOCALE ”中的每一行...
  • ..遍歷“ FEED ”中的每一行......
  • ...如果在FEED表的關鍵列中的值在LOCALE表的關鍵列中的值相匹配?
  • ......但在FEED表的位置列中的值不匹配在locale表的位置列中的值...
  • ...更新與在locale表的位置列中的值送紙表的位置列。

如果您還沒有感到困惑,這是我為它編寫的代碼:

// for each row in the "Locale" sheet... 
for(var L = LocationsRefValues.length-1;L>=0;L--) {

  // for each row in the "Feed" sheet...
  for(var F = FeedRefValues.length-1;F>=0;F--) {

    if (FeedRefValues[F][97] == LocationsRefValues[L][17] && 
        FeedRefValues[F][10] != LocationsRefValues[L][1]) {
       FeedDataSheet.getRange(F+2,10+1).setValue(LocationsRefValues[L][1]);
    }       
  }
}

現在,這段代碼工作得很好,我沒有遇到任何問題。 但是,我覺得這有點笨拙,因為完成編輯需要一段時間。 我確信有更簡單的方法來編寫和運行這段代碼。 我聽說數組可以解決這種情況,但我不知道如何去做。 因此,我為什么要尋求幫助。 任何人都可以提供幫助嗎?

請記住,我是一個完全的 Google App Script 初學者,他通過純粹的愚蠢運氣使此代碼工作,因此解決方案越簡單越好。 感謝您提前考慮我的問題。 期待收到大家的來信。

這是完整的功能(在我進行了此處建議的編輯之后。)

   function ModeratorStatus() {

  var Data = SpreadsheetApp.getActiveSpreadsheet(); // Local Spreadsheet

  var ModeratorStatusDataSheet = Data.getSheetByName("The Status (Moderators)");
  var ModeratorStatusRange = ModeratorStatusDataSheet.getRange("A2:C");
  var ModeratorStatusRefValues = ModeratorStatusRange.getValues();

 var ModeratorDataSheet = Data.getSheetByName("The Moderator_Numbers");  // DATA "Member" sheet
  //var ModeratorRefValues = ModeratorDataSheet.getRange("A2:AD").getValues();

  var ModeratorStatusObj = {};
for (var MOS = ModeratorStatusRefValues.length-1; MOS>=0; MOS--) {
  ModeratorStatusObj[ModeratorStatusRefValues[MOS][2]] = ModeratorStatusRefValues[MOS][0];
}
  var ModeratorValues = ModeratorDataSheet.getRange("A1:AD").getValues();
for (var MO = ModeratorValues.length-1; MO >=0; MO--) { // for each row in the "Moderator" sheet...
  var ModeratorVal28 = ModeratorValues[MO][28];
  if (ModeratorStatusObj[ModeratorVal28] != ModeratorValues[MO][1]) {

    ModeratorValues[MO][1] = ModeratorStatusObj[ModeratorVal28];
  }
}
var destinationRange = ModeratorDataSheet.getRange(1, 1, ModeratorValues.length, ModeratorValues[0].length);
destinationRange.setValues(ModeratorValues);

我在不同的函數中使用了代碼作為測試。 為了使它更容易

區域設置 = 版主狀態

飼料 = 主持人

如果LocationsRefValues中沒有具有不同[1]的重復[17] s,則可以通過預先為LocationsRefValues創建一個映射對象,將計算復雜度從O(n ^ 2)O(n) ,其鍵為LocationsRefValues[L][17] s,其值為LocationsRefValues[L][1] s:

var locationObj = {};
for (var L = 0; L < LocationsRefValues.length; L++) {
  locationObj[LocationsRefValues[L][17]] = LocationsRefValues[L][1];
}
for (var F = FeedRefValues.length - 1; F >= 0; F--) { // for each row in the "Feed" sheet...
  var feedVal97 = FeedRefValues[F][97];
  if (locationObj[feedVal97] != FeedRefValues[F][10]) {
    FeedDataSheet.getRange(F + 2, 10 + 1).setValue(locationObj[feedVal97]);
  }
}

謝謝@TheMaster,你可以通過在最后只調用一次setValue來加快速度,而不是在循環中調用它,可能是這樣的:

var locationObj = {};
for (var L = 0; L < LocationsRefValues.length; L++) {
  locationObj[LocationsRefValues[L][17]] = LocationsRefValues[L][1];
}
var feedValues = FeedDataSheet.getValues();
for (var F = FeedRefValues.length - 1; F >= 0; F--) { // for each row in the "Feed" sheet...
  var feedVal97 = FeedRefValues[F][97];
  if (locationObj[feedVal97] != FeedRefValues[F][10]) {
    feedValues[F + 2][10 + 1] = locationObj[feedVal97];
  }
}
var destinationRange = ss.getRange(1, 1, feedValues.length, feedValues[0].length);
destinationRange.setValues(feedValues);

您可以使用onEdit(e)觸發器來獲取對已編輯單元格的引用。 在這種情況下,您不需要遍歷整個 Locale”工作表:

function onEdit(e) {
  var range = e.range; // edited cell
  var rowIndex = range.getRow()
  var colIndex = range.getColumn()
  if (rowIndex >= LocaleRange.startRow && rowIndex <= LocaleRange.EndRow && 
      colIndex >= LocaleRange.startColumn && colIndex <= LocaleRange.EndColumn) {
    var index = rowIndex - LocaleRange.startRow
    var keyValue = LocationsRefValues[index][17]
    var newLocValue = range.getValue()
    var newFeedValues = FeedRefValues.map(function (row) {
       return (row[97] == keyValue)  newLocValue ? : row[10]
    })
    FeedDataRange.setValues(newFeedValues)
  }
}

以下是有關使用 onEdit 觸發器的文檔: https : //developers.google.com/apps-script/guides/triggers

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM