Boris P
Boris P

Reputation: 86

remove list item based on index c#

I have two lists. First list contains values such as letters and numbers. Length is [0]-[36]. Second list contains similar values and length is also [0]-[36].

I iterate second list twice with specific values to grab an Index key and when I grab Index key from second list, I want to remove items in first list based on Indexes from second one.

Problem is that second iteration doesn't work anymore, because index key has changed in first list.

I should probably convert list to an array (array has fixed index keys, list generates after) but I don't know how to add or remove index key from an array.

I don't use Linq.

Appreciate your help and suggestions BR

Code sample:

List<int> list_z = new List<int>();
List<int> list_k = new List<int>();

for (int i = 0; i < second_list.Count; i++) {
    if (second_list[i] == "K")
    {
    list_k.Add(i);
    }
}

int k = list_k.Count; 

for (int i = 0; i < k; i++) {
    first_list.RemoveAt(list_k[i]);
}

for (int i = 0; i < second_list.Count; i++)
{
    if (second_list[i] == "Z")
    {
    list_z.Add(i);
    }
}

int z = list_z.Count;
for (int i = 0; i < svi_z; i++)
    first_list.RemoveAt(lista_z[i]); //here is error, because first_list doesnt have index key number 36 anymore
}

Upvotes: 0

Views: 3635

Answers (3)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186698

When removing items from a list based on indexes, you should remove them in descending order (e.g. you should remove 11th, 8th, 3d, 2nd items - in this order). In your case:

  list_k.Sort();

  for (int i = list_k.Count - 1; i >= 0; --i)
    first_list.RemoveAt(list_k[i]);

Upvotes: 3

Blue Eyed Behemoth
Blue Eyed Behemoth

Reputation: 3872

Or you can simplify what your doing:

        // Iterate and assign null
        for (var i = 0; i < second_list.Count(); i++)
        {
            if (second_list[i] == "K")
            {
                first_list[i] = null;
            }
        }

        // Iterate and assign null
        for (var i = 0; i < second_list.Count; i++)
        {
            if (second_list[i] == "Z")
            {
                first_list[i] = null;
            }
        }

        // remove nulls without linq or lambda
        first_list.RemoveAll(delegate (string o) { return o == null; });

Upvotes: 1

Zein Makki
Zein Makki

Reputation: 30022

There is a simple solution for removing items from list at a specific index one after the other. That is to order the indexes descending, this way you'll not have any items moved around in the list.

Example:

The Below throws an error:

List<int> list = Enumerable.Range(0, 20).ToList();

List<int> indexesToRemove = new List<int>(){ 5, 13, 18 };

foreach(int i in indexesToRemove)
{
    list.RemoveAt(i);
}

While if you do this, you'll get no error:

List<int> list = Enumerable.Range(0, 20).ToList();

List<int> indexesToRemove = new List<int>(){ 5, 13, 18 };

foreach(int i in indexesToRemove.OrderByDescending(x => x))
{
    list.RemoveAt(i);
}

So in your case, you just need to call list_z = list_z.OrderByDescending(x => x).ToList(); before the loop and everything should work fine.

Or if you don't want to use linq you can do the following:

list_z.Sort((x, y) => y - x);
for (int i = 0; i < list_z.Count; i++)
    first_list.RemoveAt(lista_z[i]);
}

Upvotes: 3

Related Questions