javascript - 慢循环查找和复制
问题描述
我写了一个函数来创建报告:
- 检测特定范围内是否有特定字母(函数要求用户输入字母和列)
- 如果有字母,则抓取整行。
- 将其复制到另一张纸上。
我的代码目前正在运行,但需要很长时间才能完成。此外,如果我有超过数百个结果,我会遇到超时问题。
您可以在此处重现该问题:
https://docs.google.com/spreadsheets/d/1ggVvxquruYfckNWxhsV6-Od2J8QIkMOYpJps7qz9PkI/edit?usp=sharing
这是代码:
for(var i = 0; i<rapport.length-1; i++) {
if(colonneCode[i] == code.getResponseText()) {
ligneCode[v] = i;
v++;
}
}
for(var i = 0; i<ligneCode.length;i++) {
var codeLastRow = 12;
var copySource = sheet.getRange(ligneCode[i]+10, 1, 1, 16);
var copyTarget = feuille.getRange(feuille.getLastRow()+1,1,1,16);
copyTarget.setValues(copySource.getValues());
copySource.copyTo(copyTarget, {formatOnly:true});
}
点击个性化菜单(Évaluations Philippe Caron) -> Classement personnalisé -> 第一个输入框“2” -> 第二个输入框“e” -> 第三个是你想要的新工作表名称。
解决方案
分析您的代码
我使用这些片段来检查您的代码的时间。
let start = new Date()
Logger.log("before first for loop")
Logger.log(new Date().getTime() - start.getTime())
正如您可能猜到的那样,对于e
您工作表上的示例,直到第二个 for 循环之前的大部分代码都在大约 1 秒内运行。然而,第二个 for 循环花费了大约 45 秒。这部分:
for(var i = 0; i<ligneCode.length;i++) {
var codeLastRow = 12;
var copySource = sheet.getRange(ligneCode[i]+10, 1, 1, 16);
var copyTarget = feuille.getRange(feuille.getLastRow()+1,1,1,16);
copyTarget.setValues(copySource.getValues());
copySource.copyTo(copyTarget, {formatOnly:true});
}
为什么这段代码很慢?
因为在每次迭代中,它都会调用getRange
, getValues
, setValues
, copyTo
. 所有这些命令都要求 Apps 脚本执行从电子表格中读取和写入。这很慢。
倾倒整个范围
setValues
将整个范围收集在一个大型二维数组中并一起收集要快得多。这将需要首先在 Apps 脚本中构建范围。因此,与其将行的索引号存储在其中,不如将整行ligneCode
存储在.output
顺便说一句,您可以使用
array.push(item)
将项目添加到数组的末尾。无需跟踪索引号。
所以代替这个:
var ligneCode = [];
for(var i = 0; i<rapport.length-1; i++) {
if(colonneCode[i] == code.getResponseText()) {
ligneCode[v] = i;
v++;
}
}
构建一个数组,代表您将在新工作表中粘贴的内容。
var output = [];
for (var i = 0; i < rapport.length - 1; i++) {
if (colonneCode[i] == code.getResponseText()) {
output.push(rapport[i]);
}
}
然后,一旦您有了新工作表feuille
,您需要做的就是:
var target = feuille.getRange(
11, // first row
1, // first column
output.length, // the height of the output
output[0].length // the width of the output
);
target.setValues(output);
结果
现在以e
开头的示例为例,整个脚本运行大约需要 2 秒。
参考
推荐阅读
- php - 未找到自动加载 php 类
- ios - 使用 Xcode 的 Flutter 项目存档问题:agora_rtc_engine "Module 'agora_rtc_engine' not found"
- python - 与顺序版本相比,Python 中的慢并行代码,为什么它更慢?
- arrays - Vue js 为每个不间断的收到消息集在最后一个元素放置一个图标
- selenium - 有没有办法使用 Soft Assert 来验证文本是否包含某个字符串
- php - ERR TOO MANY REDIRECTS - 根据用户选择的城市重定向用户时
- c# - 嵌套 DataGrid 的 SelectedValue 绑定不起作用,而 ItemsSource 起作用
- sql - 从 SQL 查询向 BigQuery 表添加多个分区列
- amazon-redshift - 将动态帧写入 Redshift 时,AWS Glue 中出现“文件准备就绪”错误
- angular - 角度材料表错误:找不到具有 id 的列