迭代IList<>

时间:2015-11-13 23:42:54

标签: c# list loops

这是一个正在为我正在做的每个循环播放的场景;

基本上我想从lstMaster中删除记录,如果在lstChild中有匹配但是我得到的结果是不确定的 - 我应该删除800个左右的记录,但我只删除256个左右的记录。 / p>

外部循环是lstMaster有1600条记录。 内部循环是lstChild有800,它不存在于lstMaster中。

因此,如果在lstChild中匹配为fond,则会在lstMaster中删除该记录。

我错过了循环中的内容吗?

for(int i=lstMaster.Count-1; i > 0; i--)
   {
   for(int j=lstChildcare.Count-1; j > 0; j--)
      {
        if( lstChildcare[j].school_license == lstMaster[i].school_license )
        {
            textboxStatus.AppendText(Text = "Removing duplicate row: " + i                 + " School: " + lstMaster[i].school_name + Environment.NewLine); 
                    lstMaster.RemoveAt(i);
                    counter++;

                }

          }

      }

3 个答案:

答案 0 :(得分:2)

如果您的列表实际上是您的主列表和子列表的具体类型List<T>,则可以使用Predicate(T)方法中的RemoveAll匹配项删除不需要的项目。您还可以从IEquatable<T>继承您的ChildCare对象,以控制它被认为是平等的,并执行类似于下面的操作。我做了很多东西因为我不知道你的实际课程中除了执照以外的什么,但你可以从这个例子中得到这个想法。您可以将其直接复制并粘贴到LinqPad并运行它以试一试。

void Main()
{
    var masterChildcare = new List<ChildCare>
    {
     new ChildCare{SchoolLicense= "One"},
     new ChildCare{SchoolLicense= "Two"},
     new ChildCare{SchoolLicense= "Three"},
     new ChildCare{SchoolLicense= "Four"},
     new ChildCare{SchoolLicense= "Five"},
     new ChildCare{SchoolLicense= "Six"},
     new ChildCare{SchoolLicense= "Seven"},
     new ChildCare{SchoolLicense= "Eight"},
     new ChildCare{SchoolLicense= "Nine"},
     new ChildCare{SchoolLicense= "Ten"},
    };
    var childChildcare = new List<ChildCare>
    {
        new ChildCare{SchoolLicense= "Three"},
        new ChildCare{SchoolLicense= "Eight"},
        new ChildCare{SchoolLicense= "Nine"}
    };
    masterChildcare.Dump();

    masterChildcare.RemoveAll(childCare => childChildcare.Contains(childCare));
    masterChildcare.Dump();

}

public class ChildCare : IEquatable<ChildCare>
{
    public string SchoolLicense { get; set;}

    public bool Equals(ChildCare other)
    {
        if (other == null)
        {
            return false;
        }

        if (SchoolLicense == other.SchoolLicense)
        {
            return true;
        }
        return false;
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return false;
        }

        ChildCare other = obj as ChildCare;
        if (other == null)
        {
            return false;
        }
        return Equals(other);
    }

    public override int GetHashCode()
    {
        return SchoolLicense.GetHashCode();
    }
}

enter image description here

答案 1 :(得分:1)

由于您正在反向循环(从最后一项开始到第一项结束),那么您应该没问题。

我看到的唯一问题是从lstMaster中移除某个项目,然后尝试在lstChildcare的下一个循环中再次访问相同的索引。

要解决此问题,请在决定从lstMaster列表中删除项目后,暂停内部循环。由于您删除了该项目,因此无需继续循环。

收获这个:

lstMaster.RemoveAt(i);
counter++;

添加:

lstMaster.RemoveAt(i);
counter++;
break;

如果出于某种原因,您需要检测父列表和子列表之间的所有匹配项,您可以在循环遍历子列表之后从父列表中删除该项:

for (int i = lstMaster.Count - 1; i > 0; i--)
{
    bool delete = false;

    for (int j = lstChildcare.Count - 1; j > 0; j--)
    {
        if (lstChildcare[j].school_license == lstMaster[i].school_license)
        {
            textboxStatus.AppendText(MediaTypeNames.Text = "Removing duplicate row: " + i + " School: " + lstMaster[i].school_name + Environment.NewLine);
            delete = true;
            counter++;
        }
    }

    if(delete)
        lstMaster.RemoveAt(i);
}

答案 2 :(得分:-1)

永远不要在循环中直接从列表中删除项目。

列表的大小会改变!

因此遍历列表的for循环实际上并没有看到每个项目。

例如,如果删除第2项,则i会增加到3以获取下一个项目。但旧项目3现在变为2.所以此项目永远不会被检查。

相反,在循环中创建一个新列表items_to_be_deleted,添加需要删除的项目。

然后,删除这些项目。