Javascript 删除Google工作表(脚本)中的重复项需要太长时间才能处理

Javascript 删除Google工作表(脚本)中的重复项需要太长时间才能处理,javascript,google-apps-script,google-sheets,duplicates,Javascript,Google Apps Script,Google Sheets,Duplicates,我正在尝试删除整个工作表的重复数据,脚本工作正常,但运行需要60秒以上的时间。我是不是把这件事复杂化了,真的有一个更简单的代码来满足我的需要?处理这么简单的任务似乎需要很长时间 我的数据仅在4-12k行之间 function removeDuplicates() { var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[1]; var data = sheet.getDataRange().getValues(); va

我正在尝试删除整个工作表的重复数据,脚本工作正常,但运行需要60秒以上的时间。我是不是把这件事复杂化了,真的有一个更简单的代码来满足我的需要?处理这么简单的任务似乎需要很长时间

我的数据仅在4-12k行之间

function removeDuplicates() {
 var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[1];
 var data = sheet.getDataRange().getValues();
 var newData = [];
 for (var i in data) {
   var row = data[i];
   var duplicate = false;
   for (var j in newData) {
    if (row.join() == newData[j].join()) {
     duplicate = true;
    }
  }
//If not a duplicate, put in newData array
 if (!duplicate) {
  newData.push(row);
 }
}
//Delete the old Sheet and insert the newData array
 sheet.clearContents();
 sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}

免责声明:我不知道GoogleSheetsAPI

我提出了一些改进建议,并在代码中添加了注释。 性能的一个重要方面是缓存。因此,如果没有必要,不要做两次(或者干=不要重复你自己!)。 如果你忘了带钱包,不得不再次上楼,那么你离开前门的时间会加倍。代码也一样

如果你对性能提升感兴趣(每个人都应该如此),我建议你看看

函数removeDuplicates(){
var sheet=SpreadsheetApp.getActiveSpreadsheet().getSheets()[1];
var data=sheet.getDataRange().getValues();
var newData=[];
var newDataJoinedCache={};
//帮助循环不必反复读取相同的值
//如果您为循环准备了尽可能多的数据,它将很幸运地加快速度
对于(变量i=0,len=data.length;i
让我知道它是如何工作的,与之相比,这将节省多少时间。

如果您使用,您将大大减少迭代次数

function removeDuplicates() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
  const data = sheet.getDataRange().getValues();
  
  let newDataObject = {};
  for (let row of data) {
    newDataObject[row.join()] = row;
  }
  const newData = Object.values(newDataObject);
  
  // Clear the old Sheet and insert the newData array
  sheet.clearContents();
  sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}

现在我们有了V8,您可以使用该类了。我没有尝试过对性能进行基准测试,所以我不知道在执行速度方面是否会更好,尽管代码的可读性要高得多。尝试以下方法并告诉我它是如何进行的:

//使用Set的V8运行时版本
功能移除副本(sheetName){
var sheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var rows=sheet.getDataRange().getValues();
var重复数据值=[];
变量集=新集();
rows.forEach(函数(行){
让key=row.join();
if(set.has(key))返回;
set.add(键);
重复数据值。推送(行);
});
//删除旧工作表并插入重复数据值数组
sheet.clearContents();
sheet.getRange(1,1,DudepEdValues.length,DudepEdValues[0].length).setValues(DudepEdValues);
}
如果您对V8不满意,您可以使用@Diego的解决方案完成同样的事情……但需要做如下调整:

//使用对象键的ES5版本
功能移除副本(sheetName){
var sheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var rows=sheet.getDataRange().getValues();
var重复数据值=[];
var键={};
rows.forEach(函数(行){
var key=row.join();
如果(输入钥匙)返回;
keys[key]=true;
重复数据值。推送(行);
});
//删除旧工作表并插入重复数据值数组
sheet.clearContents();
sheet.getRange(1,1,DudepEdValues.length,DudepEdValues[0].length).setValues(DudepEdValues);
}

作为另一种方法,使用
removeDuplicates()的方法怎么样?当您的脚本被修改时,它将变成如下所示

修改脚本: 参考:

从60多秒增加到平均10-15秒左右。。。有些是3-4秒。太棒了!谢谢你的洞察力!很高兴听到这个问题是关于性能的,而不是一般的替代编码。例如,一个简单的for循环比forEach更快。如果您有兴趣根据行-列函数的结果比较行,那么答案中的第一个解决方案非常有用,因为您可以维护一个比较集和一个最终输出数组集,然后使用扩展运算符重新生成输出数组。然后您就不必使用重复数据值。按(行)
只需使用
[…设置]
function removeDuplicates() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
  const data = sheet.getDataRange().getValues();
  
  let newDataObject = {};
  for (let row of data) {
    newDataObject[row.join()] = row;
  }
  const newData = Object.values(newDataObject);
  
  // Clear the old Sheet and insert the newData array
  sheet.clearContents();
  sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}
function removeDuplicates() {
  SpreadsheetApp.getActiveSpreadsheet().getSheets()[1].getDataRange().removeDuplicates();
}