0

我在从 C# 的列表中删除项目时遇到问题。我当前的代码如下:

for (int i = current.Count - 1; i >= 0; i--)
    {
        foreach (ListItem li in sp_list.Items)
        {
            if (li.Text == current[i].uname)
            {
                current.RemoveAt(i);
            }
        }
    }

代码的目的是将列表框中的现有项目与新添加的项目进行比较,以便我知道刚刚添加了哪些项目。所以目前我正在从数据库中获取当前的列表框项目(它们存储在这里,它是一个数据绑定列表框),将它们输入到一个列表中,对于每个列表项,将它们与列表框中的项目进行比较,然后如果它们匹配,则从列表中删除该项目。

因此,最后,如果我添加两个新条目,列表应该只存储两个新添加的值。

该代码无法正常工作,因为第一项被删除得很好,但是 i 的值大于 current.count - 因此我得到一个超出范围的异常!

有人可以帮我解决这个问题吗?抱歉这个令人困惑的问题,很难解释!谢谢

4

6 回答 6

8

你可以用 Linq 做到这一点。不确定是否需要转换为 ListItem(您可以将其删除)

current.RemoveAll(x => sp_list.Items.Cast<ListItem>()
                              .Any(li => li.Text == x.uname));
于 2013-02-21T22:37:35.867 回答
3

找到匹配值并将其从列表中删除后,您希望跳出内部循环以检查下一项。

        if (li.Text == current[i].uname)
        {
            current.RemoveAt(i);
            break;
        }
于 2013-02-21T22:40:17.520 回答
3

这个怎么样:

foreach (ListItem li in sp_list.Items) {
    if (current.Contains(li.Text)) {
        current.Remove(li.Text);
    }
}
于 2013-02-21T22:40:49.343 回答
3

你的嵌套是错误的,我想你想要的,

foreach (ListItem li in sp_list.Items)
{
    for (int i = current.Count - 1; i >= 0; i--)
    {
        if (li.Text == current[i].uname)
        {
            current.RemoveAt(i);
        }
    }
}

或者,使用 linq,

// For lookup performance.
var items = new HashSet(sp_list.Items.Select(i => i.text));

current = current.Where(c => !items.Contains(c.uname)).ToList();
于 2013-02-21T22:41:55.767 回答
0

您可以以相反的顺序遍历列表并使用 RemoveAt(i) 删除项目。同样出于效率目的,您可能希望将 ListItem 文本放在 Set 中,这样您就不必为每个当前项目循环遍历 sp_list.Items。

于 2013-02-21T22:44:05.773 回答
0

在之后放置一个break声明,RemoveAt这样您就不会再次删除该项目。

于 2013-02-21T22:41:02.570 回答