循环访问列表不会检查每个对象

本文关键字:对象 检查 访问 列表 循环 | 更新日期: 2024-07-27 05:12:24

if (rowCount[i] >= 10)
{
    for (int j = 0; j < blocks.Count; j++)
    {
        if (blocks[j].Row == i)
        {
            blocks.RemoveAt(j);
            rowCount[i]--;
        }
    }
    foreach (Block b in blocks)
    {
        if (b.Row < i)
        {
            b.Row++;
            rowCount[b.Row]++;
        }
    }
}

假设我在阻止列表中有 20 个块。 我逐行调试了程序,我看到它没有检查列表中的每个块 - 它通常会留下大约 4 或 5 个未选中的块。 我是疯了还是我错过了什么?

循环访问列表不会检查每个对象

对于可接受的解决方案,更好的解决方案是以不同的方式分解它。您希望在第一个循环中执行两项操作:将rowcount[i]减少匹配项数,并从列表中删除匹配的行。现在,您将如何在没有任何循环的情况下做到这一点?第一个很简单:

rowCount[i] -= blocks.Where(block=>block.Row == i).Count();

做。第二个也很容易:

blocks.RemoveAll(block=>block.Row == i);

两行代码。没有循环。显然是正确的。

如果你不写任何循环,那么你就不会在循环条件中犯错误。

当您遍历数组时,您正在减小数组的大小,因此如果您删除索引 4,索引 5 将成为新的索引 4,并且您永远不会检查它。

修复它的两种方法是减少迭代器

if (rowCount[i] >= 10)
{
    for (int j = 0; j < blocks.Count; j++)
    {
        if (blocks[j].Row == i)
        {
            blocks.RemoveAt(j);
            rowCount[i]--;
            j--;
        }
    }
    foreach (Block b in blocks)
    {
        if (b.Row < i)
        {
            b.Row++;
            rowCount[b.Row]++;
        }
    }
}

或以相反的顺序循环

if (rowCount[i] >= 10)
{
    for (int j = blocks.Count - 1; j >= 0; j--)
    {
        if (blocks[j].Row == i)
        {
            blocks.RemoveAt(j);
            rowCount[i]--;
        }
    }
    foreach (Block b in blocks)
    {
        if (b.Row < i)
        {
            b.Row++;
            rowCount[b.Row]++;
        }
    }
}