比较两个列表时索引超出范围

时间:2012-07-20 07:36:12

标签: c# outlook-addin outlook-2010

我在互联网上搜索了一个答案。我循环使用嵌套for循环的两个列表(list1和list2),并根据三个条件删除第一个列表中的重复记录。如果这两个列表中的所有记录彼此匹配,则会出现超出范围的错误。我假设当我从第一个列表中删除所有项目时,它最终减少到0,并且没有任何记录要循环,但是使用if语句检查第一个列表的计数(如果inbox_emails_filtered_contacts。计数> 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 个答案:

答案 0 :(得分: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++;
   }
}

答案 1 :(得分:0)

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

for (int i = list1.Count - 1; i >= 0; i--)

答案 2 :(得分:0)

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

此外,您还将使用remove语句跳过电子邮件。假设i = 4,如果你在4处删除索引4将包含一个新项目,我将在下一次迭代时为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();

答案 3 :(得分: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;
    }

}

和两种获取差异的方法。

        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);