SharpUser
SharpUser

Reputation: 97

Is it possible to get the item index using Contains?

When I use if (moscowCars.Contains(cars[x].Name)) it founds the value in a collection and I believe that not necessary to use moscowCars.RemoveAt(moscowCars.FindIndex(o => o.Equals(cars[x].Name))); to find it for a second time, just: moscowCars.Remove(cars[x].Name);. Of course, I can use try & catch instead of if, but I just want to know can I get the item index using Contains?

using System.Collections.Generic;

    namespace Autoworld
    {
        class GoodCars
        {
            static List<Tech> cars = new List<Tech>();
            public class Tech
            {
                public string Name { get; set; }
                public double KM { get; set; }
            }
            static void Main()
            {
                List<string> moscowCars = new List<string>
                {
                    "GAZ-330811 Aper", "Lada Vesta Sport"
                };
                cars.Add(new Tech() { Name = "Lada Vesta Sport", KM = 190 });
                for (int x = 0; x < cars.Count; x++)
                {
                    if (moscowCars.Contains(cars[x].Name))
                    {
                        moscowCars.RemoveAt(moscowCars.FindIndex(o => o.Equals(cars[x].Name)));
                    }
                }
            }
        }
    }

Upvotes: 1

Views: 86

Answers (3)

Jozsef Baksa
Jozsef Baksa

Reputation: 104

Use simply RemoveAt if you are sure you don't have any duplicated items anyway use the second way.

  1. Solution

    static List<Tech> cars = new List<Tech>();
    public class Tech
    {
        public string Name { get; set; }
        public double KM { get; set; }
    }
    
    static void Main()
    {
        List<string> moscowCars = new List<string>
            {
                "GAZ-330811 Aper", "Lada Vesta Sport"
            };
    
        cars.Add(new Tech() { Name = "Lada Vesta Sport", KM = 190 });
    
        for (int x = 0; x < cars.Count; x++)
        {
            if (moscowCars.Contains(cars[x].Name))
            {
                moscowCars.RemoveAt(moscowCars.IndexOf(cars[x].Name));
            }
        }
    }
    
  2. Solution

    static List<Tech> cars = new List<Tech>();
    public class Tech
    {
        public string Name { get; set; }
        public double KM { get; set; }
    }
    
    static void Main()
    {
        List<string> moscowCars = new List<string>
            {
                "GAZ-330811 Aper", "Lada Vesta Sport"
            };
    
        cars.Add(new Tech() { Name = "Lada Vesta Sport", KM = 190 });
    
        for (int x = 0; x < cars.Count; x++)
        {
            if (moscowCars.Contains(cars[x].Name))
            {
                moscowCars.RemoveAll(o => o == cars[x].Name);
            }
        }
    }
    

I hope it will help.

Upvotes: 0

devNull
devNull

Reputation: 4219

You could remove the two-step process entirely and just use .Remove which will return:

true if item is successfully removed; otherwise, false. This method also returns false if itemwas not found in the List.

This would then look like:

for (int x = 0; x < cars.Count; x++) 
{ 
    moscowCars.Remove(cars[x].Name); 
}

And if you need to handle the case where no car is found to be removed, you can wrap that call in an if condition like:

for (int x = 0; x < cars.Count; x++) 
{ 
    if (!moscowCars.Remove(cars[x].Name))
    {
        // Handle no cars to remove
    }
}

Worth noting that behind the scenes, .Remove ultimately just gets the index and then removes the item at that index (which is what you were originally trying to do anyways):

public bool Remove(T item) {
    int index = IndexOf(item);
    if (index >= 0) {
        RemoveAt(index);
        return true;
    }

    return false;
}

See here for the source.


Alternatively, as others have stated, if you expect the List to contain more than item to be removed, you can use .RemoveAll:

moscowCars.RemoveAll(y => y == cars[x].Name);

And again, to handle the case where nothing is found:

if (moscowCars.RemoveAll(y => y == cars[x].Name) == 0)
{
    // Handle no cars to remove
}

Upvotes: 2

ThisIsMe
ThisIsMe

Reputation: 274

You can indeed use IndexOf(item) this will give you the index of the item, or -1 if 'item' was not found (making this method double as a "contains" as well)

Upvotes: 0

Related Questions