0

我搜索了整个互联网以找到答案。我正在使用嵌套的 for 循环遍历两个列表(list1 和 list2),并根据三个条件删除第一个列表中的重复记录。如果这两个列表中的所有记录都相互匹配,则会出现越界错误。我假设当我从第一个列表中删除所有项目时会发生这种情况,当它最终减少到 0,并且没有任何记录要循环,但是放置一个 if 语句来检查第一个列表的计数(如果 inbox_emails_filtered_contacts. Count > 0) 也无济于事。请让我知道是否有人可以告诉我为什么会出现此错误。

C#.net 中的 Outlook 加载项

for (int i = 0; i < list1.Count; i++)
{
    for (int j = 0; j < list2.Count; j++)
    {
        if (list1.Count > 0)
        {
            if ((list1[i].username == registered_user)
                && (list1[i].from_email.ToLower() == list2[j].from_email.ToLower())
                && (list1[i].email_subject == list2[j].email_subject)
                && (list1[i].email_timestamp.ToLongDateString() == list2[j].email_timestamp.ToLongDateString()))
            {
                //Remove the duplicate email from inbox_emails_filtered_contacts
                list1.RemoveAt(i);
            }
        }
    }
}
4

4 回答 4

1

我建议while在这里使用循环。如果找到匹配项,您还需要跳出内部循环以从头开始重新检查。

int i = 0;
while (i < list1.Count)
{
    int found = 0;
    for (int j = 0; j < list2.Count; j++)
    {
        if ((list1[i].username == registered_user)
            && (list1[i].from_email.ToLower() == list2[j].from_email.ToLower())
            && (list1[i].email_subject == list2[j].email_subject)
            && (list1[i].email_timestamp.ToLongDateString() == list2[j].email_timestamp.ToLongDateString()))
        {
            //Remove the duplicate email from inbox_emails_filtered_contacts
            list1.RemoveAt(i);
            found = 1;
            break;
        }
   }
   if (!found)
   {
       i++;
   }
}
于 2012-07-20T07:51:54.477 回答
0

当您迭代列表/数组同时从中删除项目时使用反向(Visual 中的片段“forr”):

for (int i = list1.Count - 1; i >= 0; i--)
于 2012-07-20T07:43:03.733 回答
0

可能是 application_emails 中有多个重复项,因此 removeAt(i) 被多次调用。你的 if 永远不会捕捉到 i 是列表中最后一项超过 2 并且你最终删除多次的情况。

此外,您还将最终跳过带有删除语句的电子邮件。假设 i=4,如果您在 4 处删除,索引 4 将包含一个新项目,并且 i 在下一次迭代中将是 5。使用while循环可能会更好

int i=0;
while (i < inbox_emails.Count) {
   bool foundDuplicate=false;
   for (int j=0;j<for (int j = 0; j < application_emails.Count; j++) {       
     if ((inbox_emails[i].username == registered_user)       
         && (inbox_emails[i].from_email.ToLower() == application_emails[j].from_email.ToLower())       
         && (inbox_emails[i].email_subject == application_emails[j].email_subject)       
         && (inbox_emails[i].email_timestamp.ToLongDateString() == application[j].email_timestamp.ToLongDateString()))       
        {       
           foundDuplicate=true;
           break;   // This is optional but it stops the j loop from continuing as we've found a duplicate
        }       
    }   
    if (foundDuplicate) {
       inbox_emails.RemoveAt(i);
    } else {
       i++;
    }
}

如果这是一个单线程,你可以使用 Linq 替换列表,确保你有一个using System.Linq

inbox_emails = inbox_emails.Where(i=> 
                 i.username != registered_user 
                 || ! application_emails.Any(j=>
                    i.from_email.ToLower() == j.from_email.ToLower()
                    && i.email_subject == j.email_subject
                    && i.email_timestamp.ToLongDateString() == j.email_timestamp.ToLongDateString()
                    )
                 ).ToList();
于 2012-07-20T07:50:38.680 回答
0

这是一个电子邮件类的实现

class Email:IComparable<Email>
{
    private static int _Id;

    public Email()
    {
        Id = _Id++;
    }

    public int Id { get; private set; }
    public string UserName { get; set; }
    public string Body { get; set; }
    public string Subject { get; set; }
    public DateTime TimeStamp { get; set; }

    public override int GetHashCode()
    {
        return UserName.GetHashCode() ^ Body.GetHashCode() ^ Subject.GetHashCode();
    }

    public int CompareTo(Email other)
    {
        return GetHashCode().CompareTo(other.GetHashCode());
    }

    public override string ToString()
    {
        return String.Format("ID:{0} - {1}", Id, Subject);
    }

    public override bool Equals(object obj)
    {
        if (obj is Email)
            return CompareTo(obj as Email) == 0;
        return false;
    }

}

和 2 种获取差异的方法。

        var list1 = new List<Email>();
        var ran = new Random();
        for (int i = 0; i < 50; i++)
        {
            list1.Add(new Email() { Body = "Body " + i, Subject = "Subject " + i, UserName = "username " + i, TimeStamp = DateTime.UtcNow.AddMinutes(ran.Next(-360, 60)) });
        }
        var list2 =  new List<Email>();

        for (int i = 0; i < 50; i++)
        {
            if (i % 2 == 0)
                list2.Add(new Email() { Body = "Body " + i, Subject = "Subject Modifed" + i, UserName = "username " + i, TimeStamp = DateTime.UtcNow.AddMinutes(ran.Next(-360, 60)) });
            else 
                list2.Add(new Email() { Body = "Body " + i, Subject = "Subject " + i, UserName = "username " + i, TimeStamp = DateTime.UtcNow.AddMinutes(ran.Next(-360, 60)) });

        }


        foreach (var item in list2.Intersect<Email>(list1))
        {
            Console.WriteLine(item);
        }

        foreach (var item in list1)
        {
            for (int i = 0; i < list2.Count; i++)
            {

                if (list2[i].Equals(item))
                {
                    Console.WriteLine(item);
                    list2.RemoveAt(i);
                    break;
                }
            }
        }

        Console.WriteLine(list2.Count);
于 2012-07-20T10:04:31.170 回答