Remove an item from a List<>

Asked

Viewed 6,301 times

5

Well, I have a method that I consult at my bank and compare with a List<Carros>. My intention is, for every item that contains as much in my query as in mine List<Carros>, I remove the item from my List<Carros>.

 private List<Carros> GetCarros(long userId, List<Carros> list)
 {
     var retornaCarros = _CarrosRepository.GetCarrosType(CarrosType.ROSA.Value, userId);

     if (retornaCarros.Count() > 0)
     {
         foreach (var itemCarros in retornaCarros)
         {
            // AQUI REMOVER O ITEM QUE TENHA NO MEU LIST<>
         }
     }

     return new List<Carros>();
 }
  • 2

    A note, check if the result has elements and redundant in this case since iteration does not happen if there are no elements (and this forces the collection to be evaluated twice).

  • @Omni Well observed.

2 answers

6

You can use the method Except(System.Linq) to solve the problem:

private IEnumerable<Carros> GetCarros(long userId, List<Carros> list)
{
    var retornaCarros = _CarrosRepository.GetCarrosType(CarrosType.ROSA.Value, userId);
    return list.Except(retornaCarros);
}

The method Except returns a list of the elements from the first list (in your case, list) which do not appear on the second list (retornaCarros).

(If you want to return one List<Carros> instead of IEnumerable<Carros> call the method .ToList() (Return list.Except(retornaCarros).ToList()) and change the method signature.

(See an example in Dotnetfiddle.)

EDIT (Regarding the dcastro comment):

Indeed in the case of your class Carros it is necessary that this knife override of the methods .GetHashCode() and .Equals(object obj) so that the .Except() is successfully carried out.

However, it is not always possible to do these overrides. Thus, one way to solve the problem is to create a class that implements IEqualityComparer<Carros>. An instance of this class can be passed to the .Except(), which in turn will use it for comparison (rather than using the base class methods object).

A possible implementation (assuming there is a property UniqueId in class Carros):

public class CarrosComparer: IEqualityComparer<Carros>
{
    public int GetHashCode(Carros carro)
    {
        return carro.UniqueId;
    }

    public bool Equals(Carros carro1, Carros carro2)
    {
        return carro1.UniqueId == carro2.UniqueId;
    }
}

Then you can do the following:

private IEnumerable<Carros> GetCarros(long userId, List<Carros> list)
{
    var retornaCarros = _CarrosRepository.GetCarrosType(CarrosType.ROSA.Value, userId);
    return list.Except(retornaCarros, new CarrosComparer());
}

(See an example in Dotnetfiddle.)

An interesting note on how the IEqualityComparer is used:

The method .Equals() is invoked only if the hash codes both instances are equal. You can check this situation by changing .GetHashCode() in the fiddle above.

  • 2

    You need to call ToList to assess the IEnumerable, or change the type of return. By the way, there is a side effect that is important to mention: Except is an operation of sets (sets) and therefore eliminates duplicates.

  • 2

    (And the answer assumes that the guy Carro correctly implements the methods Equals and GetHashCode)

4

Use the method Remove class List<T>

private List<Carros> GetCarros(long userId, List<Carros> list)
{
    var retornaCarros = _CarrosRepository.GetCarrosType(CarrosType.ROSA.Value, userId);

    // Como muito bem disse o Omni o if não é necessário
    //if (retornaCarros .Count() > 0)
    //{
        foreach (var itemCarros in retornaCarros )
        {
           list.Remove(itemCarros);
        }
    //}

    return list;
}

Note: I assume that retornaCarros is the type List<Carros>.

EDIT

As the star said in the commit to Omni’s response, so did the method Remove so that it works properly on Reference types, they will have to implement the interface Iequatable.

Supposing Carros is an entity it will have an ID field, so it is easy to implement the interface:

public class Carros : IEquatable<Carros>
{

    //Suas Propriedades
    //Seus Métodos

    public override bool Equals(object obj)
    {
        if (obj == null) return false;
        Carros objAsCarros = obj as Carros;
        if (objAsCarros == null) return false;
        else return Equals(objAsCarros);
    }

    public override int GetHashCode()
    {
        return ID;
    }

    public bool Equals(Carros other)
    {
        if(other == null)return false;
        return ID.Equals(other.ID);
    }
}

Note: Should replace ID by the name of the property of Carros that makes it unique.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.