Reputation: 540
I am having trouble with removing an item from a list in c#. My current code is below:
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);
}
}
}
The aim of the code is to compare the existing items in a list box with newly added items so I know which items have just been added. So currently I am getting the current list box items from the database (they are stored here, it is a databound list box), entering these into a list and for each of the list items, comparing them with the items in a list box and if they match, remove the item from the list.
Therefore, in the end, if I add two new entries, the list should only be storing the two newly added values.
The code does not work as the first item is removed fine, but then, the value of i is greater than current.count - and therefore I get an out of range exception!
Could someone help me with this issue? Apologies about the confusing question, it's hard to explain! Thanks
Upvotes: 1
Views: 514
Reputation: 35746
Your nesting is wrong, I think you wanted,
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);
}
}
}
alternatively, use linq,
// For lookup performance.
var items = new HashSet(sp_list.Items.Select(i => i.text));
current = current.Where(c => !items.Contains(c.uname)).ToList();
Upvotes: 4
Reputation: 568
you can travel the list in reverse order and remove items using RemoveAt(i). also for efficiency purposes you may want to put the ListItem texts in a Set so you can don't have to loop though the sp_list.Items for each of your current items.
Upvotes: 0
Reputation: 230
Put a break
statement after the RemoveAt
so you don't remove that item again.
Upvotes: 0
Reputation: 15375
How about this:
foreach (ListItem li in sp_list.Items) {
if (current.Contains(li.Text)) {
current.Remove(li.Text);
}
}
Upvotes: 3
Reputation: 32596
Once you've found the matching value, and removed it from the list, you want to break out of the inner loop to check the next item.
if (li.Text == current[i].uname)
{
current.RemoveAt(i);
break;
}
Upvotes: 4
Reputation: 236328
You can do it with Linq. Not sure if casting to ListItem needed (you can remove it)
current.RemoveAll(x => sp_list.Items.Cast<ListItem>()
.Any(li => li.Text == x.uname));
Upvotes: 8