簡體   English   中英

Apps 腳本 - For 循環很慢。 如何讓它更快?

[英]Apps Script - For loop is slow. How to make it faster?

我的電子表格有一列 (A) 有超過 1000 行的值,例如 10.99 歐元、25.99 歐元等等。 出於優化目的,我循環瀏覽此列並刪除“EUR”標記並替換“.”。 和 ”,”。 雖然代碼有效,但我的問題是執行時間超長,而且對於數千種產品,它有時會超時。 我知道我可能沒有遵循最佳實踐,但由於我的 JavaScript 技能有限,這是我能想出的最佳解決方案。 有什么幫助嗎?

 function myFunction() { var ss = SpreadsheetApp.getActive(); var sheet = ss.getSheetByName('Table'); var lastRow = sheet.getRange(1,1).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow(); for (var i = 1; i < lastRow +1; i++) { var price = sheet.getRange(i,1).getValue(); var removeCur = price.toString().replace(" EUR","").replace(".",","); sheet.getRange(i,1).setValue(removeCur); } }

這是一個經典的問題。 經典答案——你需要用cell.getValue()替換range.getValues() 以這種方式獲得二維數組。 使用循環(或映射等)處理數組。 然后使用range.setValues()一次將數組的所有值設置回工作表

https://developers.google.com/apps-script/guides/support/best-practices?hl=en

對於這種情況,它可能是這樣的:

function main() {
  var ss    = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName('Table');
  var range = sheet.getDataRange();
  var data  = range.getValues(); // get a 2d array

  // process the array (make changes in first column)
  const changes = x => x.toString().replace(" EUR","").replace(".",",");
  data = data.map(x => [changes(x[0])].concat(x.slice(1,)));

  range.setValues(data);  // set the 2d array back to the sheet
}

以防萬一,這里是與循環相同的代碼for

function main() {
  var ss    = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName('Table');
  var range = sheet.getDataRange();
  var data  = range.getValues();

  for (var i=0; i<data.length; i++) {
    data[i][0] = data[i][0].toString().replace(" EUR","").replace(".",",")
  }
  
  range.setValues(data);  
}

在這種情況下, for循環可能看起來比map更干凈。

如果您確定所有更改都在 A 列中,那么如果您以這種方式更改函數中的第三行,則可以使腳本更快:

var range = sheet.getRange("A1:A" + sheet.getLastRow());

它將范圍縮小到一列。

好吧,你可以做一些事情來改進你的代碼,不能保證它會幫助你讓它更快,但我們會看到的。

這是更新的版本

function myFunction() {
   var ss = SpreadsheetApp.getActive();
   var sheet = ss.getSheetByName('Table');
   var lastRow = sheet.getRange(1,1).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow() + 1;
   var price;
   var removeCur;
   for (var i = 1; i < lastRow; i++) {
       price = sheet.getRange(i,1).getValue();
       removeCur = price.toString().replace(" EUR","").replace(".",",");
       sheet.getRange(i,1).setValue(removeCur);
   }
}

我做了什么:

  1. 第 5 行:我刪除了循環中的 +1 並直接添加到 lastRow。 如果您有 1000 行,您將保存 1000 個分配
  2. 第 6-7 行:刪除循環中的聲明。 如果您有 1000 行,您將節省 2000 次重新聲明(不確定是否確實如此,但無論如何這是最佳實踐)

你可以使用正則表達式進行替換,所以你只做一次,但我認為它更慢,所以我在那里保留了 2 個替換

暫無
暫無

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

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