For loop 谷歌应用程序脚本-基于电子邮件正文标记电子邮件[优化代码]
我的目标是:For loop 谷歌应用程序脚本-基于电子邮件正文标记电子邮件[优化代码],for-loop,google-apps-script,gmail-api,For Loop,Google Apps Script,Gmail Api,我的目标是: 收到符合条件的电子邮件,并将其放置在标签文件夹中 收到一封新的电子邮件 这封新邮件的正文是收到的第一封邮件的副本 此新电子邮件跳过收件箱并转到标签B文件夹 下面是我如何实现它的: 所有新邮件都标记为“原始邮件” 当脚本运行时,它会将电子邮件正文与以前的所有正文进行比较 如果正文是副本,则会将其标记为“副本”,移动到“存档”,并删除“原始”标签 代码如下: function emailLabeling() { var DUPLICATE = _getLabel();
- 收到符合条件的电子邮件,并将其放置在标签文件夹中
- 收到一封新的电子邮件
- 这封新邮件的正文是收到的第一封邮件的副本
- 此新电子邮件跳过收件箱并转到标签B文件夹
- 所有新邮件都标记为“原始邮件”
- 当脚本运行时,它会将电子邮件正文与以前的所有正文进行比较
- 如果正文是副本,则会将其标记为“副本”,移动到“存档”,并删除“原始”标签
function emailLabeling() {
var DUPLICATE = _getLabel();
var labels = GmailApp.getUserLabelByName("Original");
if(labels != null){
var threads = labels.getThreads();
for (var i = 0; i < threads.length; i++){
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++){
var message = messages[j];
for (var k = i; k < threads.length; k++){
var messages_check = threads[k].getMessages();
for (var l = j; l < messages_check.length; l++){
var message_check = messages_check[l];
if(message_check.getPlainBody() == message.getPlainBody()){
if(i != k || j != l){
Logger.log(i +""+ j +""+ k +""+ l);
DUPLICATE.addToThread(threads[i]);
labels.removeFromThread(threads[i]);
GmailApp.moveThreadToArchive(threads[i]);
}
}
}
}
}
}
}
else{
Logger.log("Label Not Found!");
}
}
function _getLabel() {
var label_text = "Duplicates";
var label = GmailApp.getUserLabelByName(label_text);
if (label == null) {
var label = GmailApp.createLabel(label_text);
}
return label;
}
函数emailLabeling(){
var DUPLICATE=_getLabel();
var labels=GmailApp.getUserLabelByName(“原始”);
如果(标签!=null){
var threads=labels.getThreads();
对于(var i=0;i
代码运行良好。问题在于4个嵌套循环,随着“原始”电子邮件数量的增加,运行时间呈指数增长
有没有办法优化此代码?
是否有更明智的逻辑来实现这一想法?
任何帮助都将不胜感激。提高嵌套循环情况下性能的一种方法——特别是重复标识——是存储遍历内容的记录,而不是重复比较。例如,您可以修改消息体(给定正确的散列函数)并将散列存储为对象属性。请注意,并没有任何限制,所以您可以自己跳过散列(以获得固定长度的属性),只需让Google Apps脚本为您执行即可。当然,在生产中使用这种假设之前,测试消息的大小可能是明智的
function updateEmailLabels() {
// Use an Object to associate a message's plaintext body with the
// associated thread/message IDs (or other data as desired).
var seenBodies = {}, // When a message is read, its plaintext body is stored.
DUPLICATE = _getLabel("SO_Duplicates"),
ORIGINAL = _getLabel("SO_Original");
// getThreads() returns newest first. Start with the oldest by reversing it.
ORIGINAL.getThreads().reverse().forEach(function (thread) {
thread.getMessages().forEach(function (message, messageIndex) {
// Use this message's body for fast lookups.
// Assumption: Apps Script has no reachable limit on Object property length.
var body = message.getPlainBody();
// Compare this message to all previously seen messages:
if (!seenBodies[body]) {
seenBodies[body] = {
count: 1,
msgIndices: [ messageIndex ],
threads: [ thread ],
threadIds: [ thread.getId() ]
};
} else {
// This exact message body has been observed previously.
// Update information about where the body has been seen (or perform
// more intricate checks, i.e. compare threadIds and message indices,
// before treating this thread and message as a duplicate).
seenBodies[body].count += 1;
seenBodies[body].msgIndices.push(messageIndex);
seenBodies[body].threads.push(thread);
seenBodies[body].threadIds.push(thread.getId());
}
}); // End for-each-message.
}); // End for-each-thread.
// All messages in all threads have now been read and checked against each other.
// Determine the unique threads to be modified.
var threadsToChange = {};
for (var body in seenBodies) {
if (seenBodies[body].count === 1)
continue;
var data = seenBodies[body];
for (var threadIndex = 1; threadIndex < data.threads.length; ++threadIndex)
threadsToChange[data.threadIds[threadIndex]] = data.threads[threadIndex];
}
// Update their labels and archive status.
for (var id in threadsToChange) {
var thread = threadsToChange[id];
DUPLICATE.addToThread(thread);
ORIGINAL.removeFromThread(thread);
GmailApp.moveThreadToArchive(thread);
}
}
function _getLabel(labelText) {
var label = GmailApp.getUserLabelByName(labelText);
return label ? label : GmailApp.createLabel(labelText);
}
函数updateEmailLabels(){
//使用对象将消息的明文正文与
//关联的线程/消息ID(或所需的其他数据)。
var seenBodies={},//读取消息时,将存储其明文正文。
DUPLICATE=\u getLabel(“SO\u Duplicates”),
原件=_getLabel(“SO_原件”);
//getThreads()首先返回最新的。从最旧的开始,将其反转。
原始.getThreads().reverse().forEach(函数(线程){
thread.getMessages().forEach(函数(消息,消息索引){
//使用此邮件的正文进行快速查找。
//假设:应用程序脚本对对象属性长度没有可达到的限制。
var body=message.getPlainBody();
//将此消息与以前看到的所有消息进行比较:
如果(!seenBodies[body]){
seenBodies[身体]={
计数:1,
msgIndices:[messageIndex],
线程:[线程],
ThreadId:[thread.getId()]
};
}否则{
//这个确切的消息体之前已经被观察到了。
//更新有关已看到尸体的位置的信息(或执行
//更复杂的检查,即比较线程ID和消息索引,
//在将此线程和消息视为副本之前)。
seenBodies[body]。计数+=1;
seenBodies[body].msgIndices.push(messageIndex);
seenBodies[body].threads.push(thread);
seenBodies[body].threadIds.push(thread.getId());
}
});//每条消息的结尾。
});//每个线程结束。
//所有线程中的所有消息现在都已被读取并相互检查。
//确定要修改的唯一线程。
var threadsToChange={};
for(seenBodies中的变量体){
如果(参见主体[body]。计数==1)
继续;
var数据=seenBodies[主体];
对于(var threadIndex=1;threadIndex
你肯定会想调整重复检测位,因为我并没有确切的合格电子邮件;)我怀疑如果至少有两条消息是相同的,那么我所写的内容会将一个线程归类为重复线程,即使该线程是具有特定消息正文的唯一线程。请注意,即使在您开始查看新线程之后,您也会在该线程中的
j
th条消息之后继续启动消息检查,而不是0。这意味着您将跳过电子邮件检查。另外,当你发现一个复制的主体时,你会做什么并不清楚——我会在标签中保留前面的线程-I
,并将后面的线程-k
——移动到“复制”
标签上(你必须检查标签是否仍然存在)