Home > OS >  Problem finding indexes of items in a list
Problem finding indexes of items in a list

Time:02-16

I'm trying to find indexes of items in a list. For example number 0 in a list of numbers. With this code I have found index of zeros only when there one zero in the list. When zeros are two or more, the second index doesn't get correct. Isn't method IndexOf() the correct one to use? How can I find all the indexes of an item, not only the first? Thanks

var zerosInList = list.FindAll(x => x == 0);
            
if (zerosInList.Count > 0)
{
    foreach (var item in zerosInList) //finding indexes of zeros
        {
            indexes.Add(list.IndexOf(item));
            Console.Write("found zero in position: "); PrintList(indexes);
        }

CodePudding user response:

The List<T>.IndexOf compares elements using the default equality comparer of T. For integers, it uses value equality. All zeros in your zerosInList collection are considered to be the same. In other words, the "second zero" or "third zero" in your foreach loop is considered no different than the "first zero", therefore the IndexOf method always returns the index of the first 0 it encounters, not the particular zero that's the subject of the foreach loop's current iteration.

You can make a collection of all the zero's indexes in your original list this way:

var indexesOfZeros = new List<int>();

for (int i = 0; i < list.Count; i  )
{
    if (list[i] == 0)
    {
        indexesOfZeros.Add(i);
    }
}

CodePudding user response:

IndexOf method in C# searches one string for another. It returns the index of the string part, if one is found.

But you can try this:

    for(int i=0;i<yourFirstList.Count;i  ) 
    //yourFirstList is the list with all the numbers
    {
           if(yourFirstList.ElementAt(i).value==0){
              indexes.Add(i);
            }
        
    }
    Console.Write("found zero in position: "); PrintList(indexes);

CodePudding user response:

You could also use the following Linq expression :

List<int> zeroList = intList.Select((val,idx) => new {val,idx})
                      .Where(t => t.val == 0)
                      .Select(pp => pp.idx).ToList();

the first creates an anonymous type containing the original value & offset, the where clause filters out all instances where the value is 0 & the final select returns the index in the original list.

CodePudding user response:

I like Lambdas :D

        List<int> indexes = list.Select((item, index) => 
                item == 0 ? index : -1
            ).Where(i => i != -1).ToList();
        Console.Write("found zero in position: "); PrintList(indexes);

CodePudding user response:

List.FindAll method returns items that match your requisite, not their index. I mean if you have lets say

list[0] = 0;
list[1] = 4;
list[2] = 0;

and apply FindAll( x => x == 0); to list, you get a list which contains 2 zero values, and I think you expect indexes to contain 0 and 2 in this case. You could use .IndexOf() to accomplish your task, iterating through your items until you get a -1:

int indexOfItem = 0;
while(indexOfItem != -1 && indexOfItem < list.Count) {
    indexOfItem = list.IndexOf(0, indexOfItem);
    if (indexOfItem != -1) {
       indexes.Add(indexOfItem);
       indexOfItem  ;
    }            
}
  •  Tags:  
  • c#
  • Related